深入理解ceph-disk運行機制


谷忠言

一,背景

目前項目所用的ceph集群內部的一個節點, 一般需要管理大約十塊硬盤左右的數據存儲空間,外加一到兩塊ssd組成的journal空間。Ceph要求每個osd對應的數據盤掛載到特定的目錄,對應的ssd的journal分區也不能加載錯,否則osd 無法啟動。

目前對於數據盤的掛載采用的是基於/etc/fstab的方式。

上圖是某個節點的/etc/fstab的實例。/dev/slot* 是一個由diskctl_init.sh 腳本產生的從/dev/slot* 到/dev/sdx的映射。如下圖所示。

 

Diskctl_init.sh的原理是生成的slot 與主板物理槽位磁盤接口形成固定映射,這樣當盤符漂移的時候,/dev/slot* 始終對應物理槽位的磁盤。只要磁盤不插拔更換物理槽位,osd 就能加載正確的數據盤。

而對於ssd journal分區,則是直接采用的journalà盤符的裸映射。

 

存在的問題:

1.      Ssd journal分區的盤符裸映射, 有時候會導致機器重啟,ceph服務起不來。測試發現,正是由於盤符漂移,裸映射成為死鏈。

2.      Diskctl_init.sh 生成的slot 映射, 據同事反映,也可能有潛在的問題。具體細節不詳。

 

二,調研ceph-disk

Ceph-disk 是官方發布的一個用於部署osd 數據及journal分區或目錄的工具。基於python.安裝ceph rpm包將默認安裝此工具,安裝目錄是/usr/sbin/ceph-disk。由於此工具涉及數據盤及journal盤的分區。需要root權限。

 

ceph-disk 是如何工作的?

通過ceph-disk 部署osd, 數據分區和journal 分區將自動掛載到正確的目錄,機器重啟也能保證工作。通過ceph-disk部署osd, 將大大提高ceph部署運維的自動化程度,並降低操作出錯幾率。

以新創建OSD為例,描述ceph-disk的工作機制。

分為兩大步驟:prepare disk 和activate disk

假設/dev/sdg是OSD要使用的數據盤, /dev/sdk 是SSD, OSD要使用的journal分區在這里創建。則創建OSD 並上線的命令如下:

Ceph-disk prepare /dev/sdg /dev/sdk

Ceph-disk activate /dev/sdg1

下面詳細深入其過程。

1.      准備journal分區。

Prepare_journal_dev()調用分區工具sgdisk從/dev/sdk上划分一塊journal分區。

有以下注意要點:

a.      在調用sgdisk之前,prepare_journal_dev()會獲取ceph.conf文件中指定的osd_journal_size大小,我們的ceph.conf指定大小如下:

 

b.      實際部署環境中,由於作為journal的ssd分區並不需要很大空間,所以一個ssd很可能被多個osd共享來划分各自的journal分區,我們的環境是,一個300G的ssd 划分成5個(甚至更多的)20G的分區,掛載成5個osd的journal.

c.      Ceph-disk 在部署journal分區的時候,能自動偵測SSD盤已有分區數,不破壞已有分區,分配不沖突的新分區號來創建分區。

d.      如果不指定創建分區的uuid,ceph-disk會自動為journal分區生成一個,稱之為journal_uuid.

e.      在調用sgdisk的時候,還有一個重要的參數,--typecode. Ceph-disk 使用一個特殊的UUID 作為創建journal的typecode:

至於為何用此特殊UUID做typecode, 基本上此UUID可作為辨識分區為ceph journal的憑證,稍后深入解釋。

至此,prepare_journal_dev()已經准備好了sgdisk所需的各個參數,下面給出一個實際發生的參數例子:

/usr/sbin/sgdisk --new=6:0:+20480M--change-name="6:ceph journal" --partition-guid=6:c6422c03-d320-4633-b35d-4f43c6cdd9fa--typecode=6:45b0969e-9b03-4f30-b4c6-b4b80ceff106 --mbrtogpt -- /dev/sdk

2.      在目錄/dev/disk/by-partuuid/下為此journal分區創建link:

 

簡單介紹一下這個link如何產生的。

在調用sgdisk 創建完journal分區后,ceph-disk 調用partx更新分區表,會觸發一個塊設備/分區udev event並通知到內核。Ceph編寫了udev規則文件如下:

 

Udev daemon在收到由partx產生的udev event后,根據以上的ceph規則文件,將調用/usr/sbin/ceph-disk-udev腳本。正是在這個腳本里,在目錄/dev/disk/by-partuuid/下為此journal分區創建了link。此腳本還有另外一個掃描OSD專屬分區的功能,后文會提及。暫時不表。

 

這個link有什么用?

由於這個link是根據partition uuid生成的,可以把它看成是到特定journal分區的固定映射。后文會指出osd的journal將映射到此link:

 

由此圖看出,位於osd 數據分區里的journal是一個link,指向一個固定的位置:/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa, 再由這個link指向真正的journal分區,由此解決的盤符漂移帶來的問題。下文介紹的osd 數據分區的link也是基於此原理。

 

3.      准備OSD數據分區。

這個過程跟准備journal分區大體一樣。區別在於:

a.      調用sgdisk 使用—largest-new來使用磁盤最大可能空間。所以/dev/sdg會有一個分區sdg1,它使用所有的空間。

b.      格式化/dev/sdg1。這里對ceph-disk做了小的定制,默認使用了ext4分區格式。

c.      將此分區mount到一個臨時的目錄,然后再其中創建一個名為journal的link,指向/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa。至此,OSD的journal分區映射完成。最后umount。

d.      再次調用sgdisk,寫入一個重要的參數,--typecode. Ceph-disk 使用一個特殊的UUID 作為創建OSD的typecode:

同JOURNAL_UUID, 為何用此特殊UUID做typecode, 是因為此UUID可作為辨識分區為ceph OSD數據分區的憑證,稍后深入解釋。

 

4.      在目錄/dev/disk/by-partuuid/下為此OSD 數據分區創建link。

過程同journal的link創建過程。

 

5.      Activate過程。

Activate的命令是 ceph-disk activate /dev/sdg1。

但其實並不需要顯式的調用這個命令。原因是,准備好OSD 數據分區后,udev event 觸發了ceph-disk-udev。而ceph-disk-udev會自動調用ceph-disk activate /dev/sdg1。

下面介紹這個過程是如何自動化的。詳情參見ceph-disk-udev腳本。

新的OSD 數據分區的生成,觸發udev event, 通過ceph udev rule,最終調用ceph-disk-udev,分析該分區的typecode,發現是OSD_UUID,即表明是ceph OSD的數據分區,於是觸發ceph-disk activate /dev/sdg1:

 

Typecode 為JOURNAL_UUID的情況也一樣,只不過是通過ceph-disk activate-journal 來啟動OSD.

在介紹ceph-disk activate /dev/sdg1的具體流程。

a.      將/dev/sdg1 掛載至臨時目錄,一般為var/lib/ceph/tmp/mnt.xxx

b.      分配OSD id,及調用ceph osd create 產生 osd id

c.      初始化OSD, 如ceph-osd –mkfs –osd-data –osd-journal

d.      根據osd id 重新掛載到最終目錄: var/lib/{cluster}/osd/ceph-{osd.id}

e.      Service ceph start osd

對於osd id 已經存在,重啟osd的case,也會用到ceph-disk activate,這種情況稍有不同,不需要產生新的osd id,只需要將/dev/sdg1掛載至臨時目錄,獲取osd id后,重新掛載到最終目錄。

 

Ceph-disk 支持的其他命令如下:

    prepare             Prepare a directory or disk for aCeph OSD

    activate            Activate a Ceph OSD

    activate-journal    Activate an OSD via its journal device

    activate-all        Activate all tagged OSD partitions

    list                List disks, partitions, and CephOSDs

    suppress-activate   Suppress activate on a device (prefix)

    unsuppress-activate

                        Stop suppressingactivate on a device (prefix)

    zap                 Zap/erase/destroy a device'spartition table (and

                        contents)

特別強調幾點:

a.      Suppress的字面意思就是抑制,用在這里的意圖主要是,如果只想prepare各個分區,暫時不想activate OSD(創建osd 上線),可以使用此命令,等到所有的分區都prepare好了,unsuppress 一把,再activate-all.

b.      Activate-journal 是通過制定journal 分區來啟動osd, 如:ceph-diskactivate-journal /dev/sdk6. Ceph-disk 執行的流程為:

通過 ceph-osd -i 0 --get-journal-uuid --osd-journal /dev/sdk6 返回osd_uuid. 有了osd_uuid,就能找到osd 數據分區了,即定位/dev/disk/by-partuuid/$osd_uuid,這樣就回到了使用osd 數據分區來activate的命令邏輯,即ceph-disk activate /dev/sdg1。

這里要解釋 為什么是ceph-osd-i 0?在此條命令中, -i 后面可以跟任何一個整數,在get-journal-uuid中會被忽略。但問題是,不加-i, ceph-osd格式檢查就會報錯。

還有就是—get-journal-uuid,字面意思好像是獲取journal分區的uuid,但實際上返回的一個叫journal.header 結構體里的fsid. 此fsid的值就是 osd 數據分區的uuid. 所以命令ceph-osd -i 0 --get-journal-uuid --osd-journal /dev/sdk6 返回值是osd_uuid。不得不抱怨一把,這個命令太容易讓人產生混亂。理清邏輯是從源碼中分析得來的。從這個小問題可以看出開源軟件比起商業軟件,細處略顯粗糙,還需精細打磨。

 

c.      如果prepare不顯式指定 journal, 如 ceph-disk prepare /dev/sdg, 則處理邏輯為:

在sdg上划出兩個分區,sdg2 為20G的journal分區,sdg1為剩下空間大小的osd 數據分區。

 

 

 

注意事項

Ceph-disk的定制:

1.      default fstype ext4

2.      keyring的問題,由於目前的ceph部署沒有enablekeyring,所以屏蔽了相關代碼。

ceph-disk –v將打印更詳細的log, 如果想深入理解ceph-disk命令的運行過程,此參數非常有效。

權限問題:

chmod -R 777/home/ceph/software/ceph/var/lib/ceph/osd/ceph-*

刪除OSD產生的死鏈問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM