Ceph 集羣總體遷移方案(轉)

場景介紹:在咱們的IDC中,存在着運行了3-6年的Ceph集羣的服務器,這些服務器性能和容量等都已經沒法知足當前業務的需求,在購入一批高性能機器後,但願將舊機器上的集羣總體遷移到新機器上,固然,是保證業務不中斷的前提下,再將舊機器下架回收。本文就介紹了一種實現業務不中斷的數據遷移方案,並已經在多個生產環境執行。python

 

本文的環境均爲:Openstack+Ceph 運行虛擬機的場景,即主要使用RBD,不包含RGW,MDS。虛機的系統盤(Nova),雲硬盤(Cinder),鏡像盤(Glance)的塊均保存在共享存儲Ceph中。mysql

 

環境準備

linux

 

本文環境爲 Openstack (Kilo) + Ceph(Jewel)git

本文所用的環境包含一套完整的 Openstack 環境,一套 Ceph 環境,其中 Nova/Cinder/Glance 均已經對接到了 Ceph 集羣上,具體節點配置以下:github

主機名 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

在遷移以前,咱們建立一個虛機,一個雲盤,上傳一個鏡像,虛機此時正常運行,並將這這塊雲盤掛載到虛機上:sql

[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 來講是透明的。vim

原理簡介

 

因爲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上。

遷移思路

 

    1. 咱們首先會將新的節點的全部OSD初始化完畢,而後將這些OSD 加入到另外一棵osd tree下 (這裏簡稱原先的集羣的osd tree叫作old_tree,新建的包含新OSD的 osd tree 叫作 new_tree),這樣部署完畢後,不會對原有集羣有任何影響,也不會涉及到數據遷移的問題,此時新的OSD下尚未保存數據。

    2. 導出 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 選出兩副本(也是前兩副本)實際上是**同樣的**。

  1. 注入新的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,ntp,ntp,ntp,重要的時間對齊說三遍!

部署新的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 1 ceph osd pool set volumes crush_ruleset 0
ceph osd pool set volumes size 4 PG由active+clean,變爲 active+undersized+degraded ceph osd pool set volumes size 2 PG很快恢復active+clean
ceph osd pool set volumes crush_ruleset 2 PG 開始 backfill,須要較長時間 ceph osd pool set volumes crush_ruleset 1 PG很快恢復到active+undersized+degraded,並刪除在新節點生成的數據。
ceph osd pool set volumes crush_ruleset 3 PG 很快變爲 active+remapped。 ceph osd pool set volumes crush_ruleset2 PG很快恢復到 active+clean
ceph osd pool set volumes size 2 PG 很快變爲 active+clean,而且後臺刪除舊節點數據。 ceph osd pool set volumes size 4 PG 變爲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.confmon_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]

相關文章
相關標籤/搜索