日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Ceph 集群整体迁移方案

發布時間:2024/2/28 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Ceph 集群整体迁移方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.





場景介紹:在我們的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 組件
con192.168.100.110nova,cinder,glance,neutronmon,osd*1
com192.168.100.111nova,neutronmon,osd*1
ceph192.168.100.112
mon,osd*1

在集群整體遷移完后,各個組件分布如下,也就是說,將運行于 con,com,ceph三個節點的 Ceph 集群遷移到 new_mon_1,new_mon_2,new_mon_3 這三臺新機器上。

主機名IP地址Openstack 組件Ceph 組件
con192.168.100.110nova,cinder,glance,neutron
com192.168.100.111nova,neutron
ceph192.168.100.112

new_mon_1192.168.100.113
mon,osd*1
new_mon_2192.168.100.114
mon,osd*1
new_mon_3192.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]

  • 當副本數減少時,PG 1.0 => [osd.66] ,也就是說會刪除在osd.33上的第二副本,而在 osd.66上的主副本是維持不變的,所以在降低副本數時,底層OSD實際上只刪除了一份副本,而并沒有發生數據的遷移。

  • 當副本數增加時,PG 1.0 => [osd.66, osd.33, osd.188, osd.111],也就是說四副本的前兩個副本依舊是之前的兩個副本,而后面增加的兩副本會從主副本osd.66將數據backfill到各自的OSD上。

遷移思路

  • 我們首先會將新的節點的所有OSD初始化完畢,然后將這些OSD?加入到另一棵osd tree下?(這里簡稱原先的集群的osd tree叫做old_tree,新建的包含新OSD的 osd tree 叫做 new_tree),這樣部署完畢后,不會對原有集群有任何影響,也不會涉及到數據遷移的問題,此時新的OSD下還沒有保存數據。

  • 導出 CRUSHMAP,編輯,添加三條 CRUSH rule:

  • ?? 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 選出兩副本(也是前兩副本)其實是**一樣的**。

  • 注入新的CRUSHMAP后,我們做如下操作:

    ???將所有pool(當然建議一個pool一個pool來,后面類似) 的 CRUSH RULE 從? crush_rule_0 設置為 crush_rule_1 ,此時所有PG均保持active+clean,狀態沒有任何變化。

    ? ?? 將所有pool的副本數設置為4, 由于此時各個 pool 的CRUSH RULE 均為 crush_rule_1 ,而這個 RULE 只能選出兩副本,剩下兩副本不會被選出,所以此時所有PG狀態在重新 peer 之后,變為 active + undersized + degraded,由于不會生成新的三四副本,所以集群沒有任何數據遷移(backfill) 動作,此步驟耗時短暫。

    ??? 將所有pool的 CRUSH RULE 從 crush_rule_1 設置為 crush_rule_2,此時上一條動作中沒有選出的三四副本會從 new_tree 下選出,并且原先的兩副本不會發生任何遷移,整個過程宏觀來看就是在 old_tree -> new_tree 單向數據復制克隆生成了新的兩副本,而舊的兩副本沒有移動。此時生成新的兩副本耗時較長,取決于磁盤性能帶寬數據量等,可能需要幾天到一周的時間,所有數據恢復完畢后,集群所有PG變為 active+clean 狀態。

    ? ?? 將所有pool的 CRUSH RULE 從 crush_rule_2 設置為 crush_rule_3,此時所有PG狀態會變為 active+remapped,發生的另一個動作是,原先四副本的PG的主副本是在 old_tree 上的某一個OSD上的,現在這個PG的主副本變為 new_tree下的選出的第一個副本,也就是發生了主副本的切換。比如原先 PG 1.0 => [osd.a, osd.b, osd.c, osd.d] 在這步驟之后會變成 PG 1.0 => [osd.c, osd.d]。原先的第三副本也就是new_tree下的第一副本升級為主副本。

    ??? 將所有pool的副本數設置為2,此時PG狀態會很快變為 active+clean,然后在OSD層開始刪除 old_tree 下的所有數據。此時數據已經全部遷移到新的OSD上。

  • 遷移指令

    1.初始化新的OSD

    一定要記住:在部署目錄下的ceph.conf內添加 osd_crush_update_on_start =false,再開始部署新的OSD,并且一定要檢查新節點配置,包括但不限于: yum 源,免秘鑰配置,ceph的版本,主機名,防火墻,selinux,ntpntpntp,重要的時間對齊說三遍!

    部署新的OSD:

    ### 前往部署目錄
    cd /root/cluster
    echo "osd_crush_update_on_start = false " >> ceph.conf
    ceph-deploy --overwrite-conf osd prepare new_mon_1:sdb ?new_mon_2:sdb ?new_mon_3:sdb --zap-disk
    ceph-deploy --overwrite-conf osd activate ?new_mon_1:sdb1 ?new_mon_2:sdb1 ?new_mon_3:sdb1

    添加完這三個OSD后,集群總共有六個OSD,此時不會有數據遷移。結構如下:

    [root@ceph ~]# ceph osd tree
    ID WEIGHT ?TYPE NAME ? ? UP/DOWN REWEIGHT PRIMARY-AFFINITY
    -1 0.75000 root default ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    -2 0.25000 ? ? host ceph ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    0 0.25000 ? ? ? ? osd.0 ? ? ?up ?1.00000 ? ? ? ? ?1.00000
    -3 0.25000 ? ? host con ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    1 0.25000 ? ? ? ? osd.1 ? ? ?up ?1.00000 ? ? ? ? ?1.00000
    -4 0.25000 ? ? host com ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    2 0.25000 ? ? ? ? osd.2 ? ? ?up ?1.00000 ? ? ? ? ?1.00000
    3 ? ? ? 0 osd.3 ? ? ? ? ? ? ?up ?1.00000 ? ? ? ? ?1.00000
    4 ? ? ? 0 osd.4 ? ? ? ? ? ? ?up ?1.00000 ? ? ? ? ?1.00000
    5 ? ? ? 0 osd.5 ? ? ? ? ? ? ?up ?1.00000 ? ? ? ? ?1.00000

    構建新的new_root根節點,并將這三個新的OSD加入到新的根節點下(注意OSD和主機的物理對應關系):

    ceph osd crush add-bucket new_root ?root
    ceph osd crush add-bucket new_mon_1 host
    ceph osd crush add-bucket new_mon_2 host
    ceph osd crush add-bucket new_mon_3 host
    ceph osd crush move new_mon_1 root=new_root
    ceph osd crush move new_mon_2 root=new_root
    ceph osd crush move new_mon_3 root=new_root
    ceph osd crush add osd.3 0.25 host=new_mon_1
    ceph osd crush add osd.4 0.25 host=new_mon_2
    ceph osd crush add osd.5 0.25 host=new_mon_3

    此時,新的 TREE 結構如下:

    [root@ceph ~]# ceph osd tree
    ID WEIGHT ?TYPE NAME ? ? ? ? ?UP/DOWN REWEIGHT PRIMARY-AFFINITY
    -5 0.75000 root new_root ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    -6 0.25000 ? ? host new_mon_1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    3 0.25000 ? ? ? ? osd.3 ? ? ? ? ? up ?1.00000 ? ? ? ? ?1.00000
    -7 0.25000 ? ? host new_mon_2 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    4 0.25000 ? ? ? ? osd.4 ? ? ? ? ? up ?1.00000 ? ? ? ? ?1.00000
    -8 0.25000 ? ? host new_mon_3 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    5 0.25000 ? ? ? ? osd.5 ? ? ? ? ? up ?1.00000 ? ? ? ? ?1.00000
    -1 0.75000 root default ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    -2 0.25000 ? ? host ceph ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    0 0.25000 ? ? ? ? osd.0 ? ? ? ? ? up ?1.00000 ? ? ? ? ?1.00000
    -3 0.25000 ? ? host con ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    1 0.25000 ? ? ? ? osd.1 ? ? ? ? ? up ?1.00000 ? ? ? ? ?1.00000
    -4 0.25000 ? ? host com ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
    2 0.25000 ? ? ? ? osd.2 ? ? ? ? ? up ?1.00000 ? ? ? ? ?1.00000

    2.編輯 CRUSH MAP

    導出CRUSH MAP,并編輯添加三條新的 CRUSH RULE:

    ### 導出CRUSH MAP
    ceph osd getcrushmap -o map
    crushtool -d map -o map.txt
    ### 在map.txt 最后添加以下內容
    vim map.txt

    # rules
    rule replicated_ruleset {
    ? ? ? ?ruleset 0
    ? ? ? ?type replicated
    ? ? ? ?min_size 1
    ? ? ? ?max_size 10
    ? ? ? ?step take default
    ? ? ? ?step chooseleaf firstn 0 type host
    ? ? ? ?step emit
    }
    >>>>>>>>>>>>>> 添加開始 ?>>>>>>>>>>
    rule replicated_ruleset1 {
    ? ? ? ?ruleset 1
    ? ? ? ?type replicated
    ? ? ? ?min_size 1
    ? ? ? ?max_size 10
    ? ? ? ?step take default
    ? ? ? ?step chooseleaf firstn 2 type host
    ? ? ? ?step emit
    }
    rule replicated_ruleset2 {
    ? ? ? ?ruleset 2
    ? ? ? ?type replicated
    ? ? ? ?min_size 1
    ? ? ? ?max_size 10
    ? ? ? ?step take default
    ? ? ? ?step chooseleaf firstn 2 type host
    ? ? ? ?step emit
    ? ? ? ?step take new_root
    ? ? ? ?step chooseleaf firstn 2 type host
    ? ? ? ?step emit
    }
    rule replicated_ruleset3 {
    ? ? ? ?ruleset 3
    ? ? ? ?type replicated
    ? ? ? ?min_size 1
    ? ? ? ?max_size 10
    ? ? ? ?step take new_root
    ? ? ? ?step chooseleaf firstn 2 type host
    ? ? ? ?step emit
    }
    <<<<<<<<<<<< 添加結束 ?<<<<<<<<<<<<
    # end crush map

    ### 編譯 CRUSH MAP,并注入到集群中

    crushtool -c map.txt -o map.bin
    ceph osd setcrushmap -i map.bin

    3. 開始遷移數據

    到目前為止的所有操作均不會發生數據遷移,對線上業務也就沒有影響,下面我們要開始通過修改 POOL 的 CRUSH RULESET 和 副本數來實現數據的整體遷移(這里我們取 volumes 池來介紹):

    ###確認當前 volumes 池使用的是 crush_ruleset 0
    [root@ceph cluster]# ceph osd pool get volumes crush_ruleset
    crush_ruleset: 0

    ### 將 volumes 池的 crush_ruleset 設置為 1,設置完后,集群一切正常,PG均為active+clean
    [root@ceph cluster]# ceph osd pool set volumes crush_ruleset 1
    set pool 1 crush_ruleset to 1

    ### 將 volumes 池的 副本數設置為4, 設置完后,PG經過短暫 Peer,變為 active+undersized+degraded
    [root@ceph cluster]# ceph osd pool set volumes size 4
    set pool 1 size to 4

    [root@ceph cluster]# ceph -s
    ? ?cluster 166889ab-fa7b-4a07-83da-6dfc92913a3d
    ? ? health HEALTH_WARN
    ? ? ? ? ? ?256 pgs degraded
    ? ? ? ? ? ?256 pgs undersized
    ? ? ? ? ? ?recovery 183984/368006 objects degraded (49.995%)
    ? ? 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 182, quorum 0,1,2 con,com,ceph
    ? ? osdmap e106: 6 osds: 6 up, 6 in
    ? ? ? ? ? ?flags sortbitwise,require_jewel_osds
    ? ? ?pgmap v23391: 768 pgs, 3 pools, 403 MB data, 92011 objects
    ? ? ? ? ? ?1523 MB used, 1532 GB / 1533 GB avail
    ? ? ? ? ? ?183984/368006 objects degraded (49.995%)
    ? ? ? ? ? ? ? ? 512 active+clean
    ? ? ? ? ? ? ? ? 256 active+undersized+degraded


    [root@ceph cluster]# ceph osd pool set volumes crush_ruleset 2
    set pool 1 crush_ruleset to 2

    ### 等到 volumes 池的所有PG均變為 active+clean 后,將 volumes 池的 crush_ruleset 設置為3, 此步驟后,volumes 池的 PG狀態變為 active+remapped。但是不影響集群IO。

    [root@ceph cluster]# ceph osd pool set volumes crush_ruleset 2
    set pool 1 crush_ruleset to 2

    set pool 1 crush_ruleset to 3

    ### 此時,將 volumes 池的 副本數 設置為2 ,此時 PG 狀態經過 peer 之后,很快變為 active+clean ,volumes 池的兩副本均落在新的節點下,并且后臺在自行刪除之前舊節點上的數據。

    [root@ceph cluster]# ceph osd pool set volumes size ?2


    注意事項

    由于本次數據遷移是在生產環境上執行的,所以沒有直接執行將數據從舊節點直接?mv到新節點,而是選擇了執行步驟較為復雜的上面的方案,先?scp?到新節點,再?rm掉舊節點的數據。并且每一個步驟都是可以快速回退到上一步的狀態的,對于生產環境的操作,是比較友好的。在本次方案測試過程中,遇到了如下的一些問題,需要引起充分的注意:

    • Ceph 版本不一致: 由于舊的節點的 Ceph 版本為 0.94.5 ,而新節點安裝了較新版本的 10.2.7, 在副本 2=>4 的過程中Peer是正常的,而將池的crush_ruleset 設置為3 ,也就是將新節點的 PG 升級為主副本后,PG由新節點向舊節點發生Peer,此時會一直卡住,PG始終卡在了?remapped + peering,導致該 pool 無法IO。在將新舊節點 Ceph 版本一致后(舊節點升級,新節點降級),此現象得以消除。 為了確保此現象不會在實際操作中發生,應該在變更之前,新建一個測試pool,對其寫入部分數據,再執行所有數據遷移指令,查看此過程是否順暢,確認無誤后,再對生產pool進行操作!

    • 新節點 OSD 的重啟問題: 如果沒有添加了osd_crush_update_on_start?這個配置參數,那么當新節點的OSD重啟后,會自動添加到默認的?root=default?下,然后立刻產生數據遷移,因此需要添加這個參數,保證OSD始終位于我們人為指定的節點下,并不受重啟影響。這是個基本的Ceph運維常識,但是一旦遺忘了,可能造成較為嚴重的影響。更不用說防火墻時鐘這些配置了。

    • 集群性能降低:總體來說,在副本從2克隆為4這段時間(約2-3天,取決于集群數據量)內,集群的實際IO表現降低到變更前的 25%->80% 左右,時間越往后表現越接近變更前,這雖然不會導致客戶端的IO阻塞,但從客戶反饋來看,可以感知到較為明顯的卡頓。因此克隆時間應該選擇業務量較低的節假日等。

    • 新節點IP不cluster_network范圍內:這個比較好解決,只需要增大部署目錄ceph.conf內的cluster_network?或者?public_network的掩碼范圍即可,不需要修改舊節點的,當然網絡還是要通的。

    • 變更的回退:對于生產環境來說,盡管執行步驟幾乎是嚴謹不會出錯的,但是難免會遇到意外情況,就比如上面的版本不一致導致的 peer 卡住現象。因此我們需要制定完善的回退步驟,在意外發生的時候,能夠快速將環境回退到上一步集群正常的狀況,而不是在意外發生時驚出一身冷汗,雙手顫抖得敲指令。。。所以,下面的表格給出了這個變更操作的每一步的回退步驟:

    變更步驟實際影響回退指令回退影響
    ceph osd pool set volumes crush_ruleset 1ceph osd pool set volumes crush_ruleset 0
    ceph osd pool set volumes size 4PG由active+clean,變為 active+undersized+degradedceph osd pool set volumes size 2PG很快恢復active+clean
    ceph osd pool set volumes crush_ruleset 2PG 開始 backfill,需要較長時間ceph osd pool set volumes crush_ruleset 1PG很快恢復到active+undersized+degraded,并刪除在新節點生成的數據。
    ceph osd pool set volumes crush_ruleset 3PG 很快變為 active+remapped。ceph osd pool set volumes crush_ruleset2PG很快恢復到 active+clean
    ceph osd pool set volumes size 2PG 很快變為 active+clean,并且后臺刪除舊節點數據。ceph osd pool set volumes size 4PG 變為active+remapped。

    為何不直接遷移數據到新節點?總體來看數據遷移過程,最耗時的地方是數據從兩副本變為四副本的過程,其余過程是短暫且可以快速回退的,而如果直接將池的 crush_ruleset 設置為 3 ,數據開始從舊節點直接backfill到新節點上,其實這么做也是可以的,但是這里我們就會遇到一個問題,一旦數據復制了一天或者一段時間后,集群出現了問題,比如性能驟降,要求必須回退到操作之前的狀態,此時已經有部分PG完成了遷移,也就是說舊節點上的兩副本已經刪除了,那么回退到上一步后,還會發生數據從新節點向舊節點的復制,那么之前復制了多久的數據,可能就需要多久來恢復舊節點上刪除的數據,這很不友好。而用了我們的方法來復制數據的話,不會存在這個問題,因為這里的方法在最后一步將池的副本設置為2之前,舊節點上的數據始終都是在的,并且不會發生任何遷移,我們可以在任意意外情況下,通過幾條指令將集群恢復到變更之前的狀態。


    MON的遷移

    原理介紹

    相比于 OSD 的數據遷移,MON 的遷移比較省時省力一些,步驟相對簡單,但是里面涉及的原理比較復雜,操作也需要細心又細心。

    首先,我們的環境為典型的 Openstack+Ceph的環境,其中 Openstack 的三個組件: Nova/Cinder/Glance 均已經對接到了Ceph集群中,也就是說虛機系統盤,云硬盤,鏡像都保存在Ceph中。而這三個客戶端調用Ceph的方式不太一樣:

    • Glance :上傳下載鏡像等時,需要新建一個調用 librbd 的 Client 來連接 Ceph集群。

    • Cinder :

      • 創建刪除云盤時,新建一個調用 librbd 的 Client 來連接 Ceph 集群。

      • 掛載卸載云盤時,由Nova調用librbd來實現該操作。

    • Nova : 虛機(qemu-kvm進程)相當于一個始終在調用librbd的Client,并且進程始終都在。

    我們需要知道的是,當一個 Client需要連接 Ceph 集群時,它首先通過自己的用戶名和秘鑰(client.cinder/client.nova...) 來連接到?/etc/ceph/ceph.conf配置文件指定IP的MON,認證成功后,可以獲取集群的很多MAP( monmap,osdmap,crushmap...),通過這些 MAP,即可向 Ceph 集群讀取數據。

    對于一個虛機進程(qemu-kvm)來說,虛機啟動之初,它即獲取到了集群的 monmap, 而當所連接 MON 的 IP 變化時,比如這個 MON 掛掉時,它便會嘗試連接 monmap 里面的其他 IP 的 MON,如果每個MON都掛了,那么這個 Client 就不能連接上集群獲取最新的 monmap,osdmap等。下面我們以一個 pid為3171的 qemu-kvm 進程來演示這一過程:

    [root@con ~(keystone_admin)]# ps -ef|grep kvm
    qemu ? ? ? ?3171 ? ? ? 1 17 14:32 ? ? ? ? ?00:31:08 /usr/libexec/qemu-kvm -name guest=instance-0000000b.........

    [root@con ~(keystone_admin)]# netstat -tnp |grep 3171|grep 6789
    tcp ? ? ? ?0 ? ? ?0 192.168.100.110:59926 ? 192.168.100.112:6789 ? ?ESTABLISHED 3171/qemu-kvm

    可以看到,這個進程連接著IP為?192.168.100.112?的 MON,而我們手動將這個IP的 MON 停掉,則會發現這個進程又連接到了剩余兩個IP的MON之一上:

    [root@con ~(keystone_admin)]# ssh 192.168.100.112 systemctl stop ceph-mon.target

    [root@con ~(keystone_admin)]# netstat -tnp |grep 3171|grep 6789
    tcp ? ? ? ?0 ? ? ?0 192.168.100.110:48792 ? 192.168.100.111:6789 ? ?ESTABLISHED 3171/qemu-kvm ?

    因此,如果我們每次都增加一個MON,再刪除一個MON,那么在刪除一個MON之后,之前連接到這個MON上的 Client 會自動連接到一個其他MON,并且再獲取最新的monmap。那么我們增刪過程就是:

    • 原先有三個MON: con, com, ceph

    • 增加 new_mon_1,變為四個: con, com, ceph, new_mon_1

    • 刪除con,變為三個:com, ceph, new_mon_1

    • 增加 new_mon_2,變為四個: com, ceph, new_mon_1, new_mon_2

    • 刪除com,變為三個:ceph, new_mon_1, new_mon_2

    • 增加 new_mon_3,變為四個: ceph, new_mon_1, new_mon_2, new_mon_3

    • 刪除con,變為三個:new_mon_1, new_mon_2, new_mon_3

    Nova 側的一個問題

    在實際操作中,發現了一個問題,會導致虛機無法重啟等問題。

    當虛機掛載一個云硬盤時,Nova 會將掛載這個云盤時所連接的MON IP 寫入到數據庫中,而在修改完MON的IP后,新的MON IP不會被更新到數據庫中,而虛機啟動時會加載 XML 文件,這個文件由數據庫對應字段生成,由于沒有更新 MON IP,所以 qemu-kvm 進程在啟動時,會嘗試向舊的MON IP發起連接請求,當然,舊MON已經刪除,導致連接不上而卡住,最終致使虛機進程啟動了,但是虛機狀態始終不能更新為 RUNNING。

    可以通過打開客戶端的ceph.conf?內的?debug_rbd=20/20,查看qemu-kvm進程調用librbd時生成的log發現進程在啟動時始終嘗試連接舊的MON IP。

    這里,我們只能手動修改數據庫中記錄的IP地址來確保虛機重啟后能夠連接上新的MON,需要注意的是,僅僅修改虛機XML文件是無法生效的,因為會被數據庫內的字段覆蓋而連上舊MON:

    ### 具體字段為:
    mysql =>
    nova ?=> block_device_mapping => connection_info

    *************************** 23. row ***************************
    ? ? ? ? ? created_at: 2018-03-19 08:50:59
    ? ? ? ? ? updated_at: 2018-03-26 06:32:06
    ? ? ? ? ? deleted_at: 2018-03-26 09:20:02
    ? ? ? ? ? ? ? ? ? id: 29
    ? ? ? ? ?device_name: /dev/vdb
    delete_on_termination: 0
    ? ? ? ? ?snapshot_id: NULL
    ? ? ? ? ? ?volume_id: 39c76d96-0f95-490c-b7db-b3da6d17331b
    ? ? ? ? ?volume_size: NULL
    ? ? ? ? ? ?no_device: NULL
    ? ? ?connection_info: {"driver_volume_type": "rbd", "serial": "39c76d96-0f95-490c-b7db-b3da6d17331b", "data": {"secret_type": "ceph", "name": "volumes/volume-39c76d96-0f95-490c-b7db-b3da6d17331b", "secret_uuid": "0668cc5e-7145-4b27-8c83-6c28e1353e83", "qos_specs": null, "hosts": ["192.168.100.110", "192.168.100.111", "192.168.100.112"], "auth_enabled": true, "access_mode": "rw", "auth_username": "cinder", "ports": ["6789", "6789", "6789"]}}
    ? ? ? ?instance_uuid: 4f52191f-9645-448f-977b-80ca515387f7
    ? ? ? ? ? ? ?deleted: 29
    ? ? ? ? ?source_type: volume
    ? ? destination_type: volume
    ? ? ? ? guest_format: NULL
    ? ? ? ? ?device_type: disk
    ? ? ? ? ? ? disk_bus: virtio
    ? ? ? ? ? boot_index: NULL
    ? ? ? ? ? ? image_id: NULL

    遷移指令

    這里,我們使用 ceph-deploy 來增刪 MON 節點,主要是為了操作的簡潔和安全性著想。

    首先,我們需要將新的三個MON的IP地址加入到所有節點的/etc/ceph/ceph.conf的mon_host?字段中。保證此時mon_host內是六個MON的IP地址。

    ### 添加 new_mon_1
    [root@ceph cluster]# ceph-deploy mon add new_mon_1
    [root@ceph cluster]# ceph -s
    ? ?cluster 166889ab-fa7b-4a07-83da-6dfc92913a3d
    ? ? health HEALTH_OK
    ? ? monmap e48: 4 mons at {ceph=192.168.100.112:6789/0,com=192.168.100.111:6789/0,con=192.168.100.110:6789/0,new_mon_1=192.168.100.113:6789/0}
    ? ?
    ### 刪除 con ?刪除完后,建議等待1-3min再添加新的MON,使得qemu-kvm進程可以建立新的socket鏈接。
    [root@ceph cluster]# ceph-deploy mon destroy con
    [root@ceph cluster]# ceph -s
    ? ?cluster 166889ab-fa7b-4a07-83da-6dfc92913a3d
    ? ? health HEALTH_OK
    ? ? monmap e49: 3 mons at {ceph=192.168.100.112:6789/0,com=192.168.100.111:6789/0,new_mon_1=192.168.100.113:6789/0}
    ? ?
    ### 依次添加 new_mon_2 ,刪除 com,添加 new_mon_3 , 刪除 ceph:
    [root@ceph cluster]# ceph-deploy mon add new_mon_2
    [root@ceph cluster]# ceph-deploy mon destroy com
    ### 等待1-3min,
    [root@ceph cluster]# ceph-deploy mon add new_mon_3
    [root@ceph cluster]# ceph-deploy mon destroy ceph

    [root@con ~(keystone_admin)]# ceph -s
    cluster 166889ab-fa7b-4a07-83da-6dfc92913a3d
    ? ? health HEALTH_OK
    ? ? monmap e53: 3 mons at {new_mon_1=192.168.100.113:6789/0,new_mon_2=192.168.100.114:6789/0,new_mon_3=192.168.100.115:6789/0}

    此時,將所有節點/etc/ceph/ceph.conf內的mon_host字段中原先的MON刪除,只保留三個新的MON IP地址

    Glance & Cinder & Nova 服務重啟

    無需重啟 Glance 服務。

    需要重啟?所有計算節點的 nova-compute 和?控制節點的 Cinder 服務,否則會導致虛機無法創建等問題。

    ## 在計算節點
    openstack-service restart nova-compute
    ## 在控制節點
    openstack-service restart cinder

    Nova

    由于 nova 不會更新之前的已經掛載的磁盤所連接的MON IP 信息,這會導致虛機在重啟等動作時,嘗試連接到舊的已經被摧毀的MON的地址,導致動作卡住,因此這里要單獨改一下數據庫內的MON IP 信息:

    這里我們將 192.168.100.110/111/112 改為 192.168.100.113/114/115

    mysql >>

    use nova;
    update ?block_device_mapping set connection_info=(replace(connection_info,'192.168.100.110','192.168.100.113'));
    update ?block_device_mapping set connection_info=(replace(connection_info,'192.168.100.111','192.168.100.114'));
    update ?block_device_mapping set connection_info=(replace(connection_info,'192.168.100.112','192.168.100.115'));

    exit;

    更新完數據庫后,這次數據遷移算是大功告成了。為何不需要重啟虛機服務呢,這里再做一些簡單的介紹:

    qemu-kvm 虛機進程是一個長連接的 Ceph Client,自虛機啟動后,進程就和 Ceph 集群保持著連接,在我們更改 MON 后,這些 Client 會自動嘗試重連 monmap 里面的其他MON,從而更新 monmap, 來獲取最新的 MON 。修改?/etc/ceph/ceph.conf不會對虛機進程產生影響,除非虛機重啟等,但是,虛機可以通過更新 monmap 的方式來感知集群MON的改變。

    參考文檔

    • [如何更改基于rbd塊設備的虛機的monitor ip] [https://opengers.github.io/openstack/how-to-change-guest-monitor-ip-with-rbd-disk/#%E6%9F%A5%E7%9C%8B%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%BD%93%E5%89%8D%E8%BF%9E%E6%8E%A5%E7%9A%84monitor-ip]

    • [Ceph Monitor hardcoded IPs in Nova database] [https://bugzilla.redhat.com/show_bug.cgi?id=1414124]



    總結

    以上是生活随笔為你收集整理的Ceph 集群整体迁移方案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。