Ceph 提供了物件儲存,可作為儲存引擎在 JuiceFS 中使用。這一組合非常適合雲端計算、大資料分析和機器學習等資料密集型應用場景。
在日常部署中可直接透過 Ceph RADOS 配合 JuiceFS 使用,無需部署 RGW。基於此方案實踐以及運維中的常見問題,結合Ceph 官方文件整理了這篇部落格,旨在幫助那些不太熟悉 Ceph 的工程師順利部署和運維 Ceph,並與 JuiceFS 進行對接。
閱讀之前,簡單接下來操作中涉及到的 Ceph 基本概念:
-
cephadm 是 Ceph 叢集專門的運維管理工具,我們會用他初始化 Ceph 叢集
-
OSD(Object Storage Daemon)是 Ceph 叢集的儲存服務例項,分配給 Ceph 使用的每一塊盤,都由一個 OSD 來負責管理
-
放置組(Placement Group,PG)可以簡單想象成是 Ceph 中的「虛擬目錄」,為 Ceph 中儲存的大量物件進行分組。同一目錄下的變更操作會加鎖執行,而不同的目錄之間可以進行併發操作。因此 PG 的數目如果太小,會由於衝突導致效能不佳,PG 數目過大,消耗的資源也會上升。在下方的教程裡會遵循官方推薦的經驗值計算方法進行設定
環境準備
文件中以下方環境作為示範:
- 作業系統:Ubuntu 22.04 LTS
- 核心版本:5.15.0-72-generic
- 資料盤:每臺節點 8 塊本地 NVME SSD
- 記憶體:256G
- Ceph 版本:quincy v17.2.6
共計 16 節點,每個節點 8 塊 SSD 盤(未格式化),在開始操作前,首先在 1 號節點配置好所有節點的免密登入,並且將節點資訊記錄在 /etc/hosts,類似:
10.38.0.1 ceph-node01
10.38.0.2 ceph-node02
10.32.0.3 ceph-node03
...
10.32.0.16 ceph-node16
準備完畢以後,接下來會把 ceph-node01 做為操作(兼 Ceph 主控)節點,接下來將會在這臺機上進行所有 Ceph 相關的安裝、運維操作,因此提前安裝 pssh,方便後續批次操作:
apt install pssh
pssh 也就是 Parallel SSH,可以方便地併發 SSH 到多個節點、批次執行命令,這個工具需要讀取主機列表,因此將所有節點(主控除外)的主機名記錄到文字檔案裡:
ceph-node02
ceph-node03
...
節點基礎設施
如果尚未搭建時鐘同步,需要手動安裝:
apt install chrony
# 檢視能連線到的 servers
# 如外網不通則需要改配置連內部伺服器,如果不清楚如何配置,聯絡雲服務商技術支援
chronyc sources
# 時鐘同步需要在所有節點設定,此處僅示範批次安裝 chrony 的命令
# 如果需要更多配置,需要自行操作
parallel-ssh -h hosts.txt -i apt install chrony
如果節點開啟了 swap(檢查 /etc/fstab 是否存在 swap 字樣),那麼首先需要對所有節點禁用 swap:
swapoff -a
# 將 fstab 中的專案進行註釋禁用
sed -i.bak "s/\/swap.img/# \/swap.img/" /etc/fstab
# 在主控節點上執行上方命令以後,還需要批次在所有其他節點執行
parallel-ssh -h hosts.txt -i swapoff -a
parallel-ssh -h hosts.txt -i 'sed -i.bak "s/\/swap.img/# \/swap.img/" /etc/fstab'
安裝 Ceph
Docker 和映象搬運
在所有節點上安裝 Docker:
apt install docker.io
parallel-ssh -h hosts.txt -i apt install docker.io
在後續的安裝過程中,ceph 和 node-exporter 這兩個映象是所有節點都需要的,因此推薦提前拉取下來、手動分發到所有節點。如果不做這一步,後續 cephadm 會從官方源拉,取決於當地網路環境,可能會非常慢。
docker image save quay.io/ceph/ceph quay.io/prometheus/node-exporter | gzip > images.tar.gz
parallel-scp -h hosts.txt ./images.tar.gz /tmp/
parallel-ssh -h hosts.txt -i 'docker load -i /tmp/images.tar.gz'
# 確認所有節點都載入成功後,清理映象
parallel-ssh -h hosts.txt -i rm /tmp/images.tar.gz
部署 Ceph 主控
Ubuntu 22 可以方便地從系統源安裝 cephadm,但對於其他 Ubuntu 版本或者其他系統,則可能需要手動安裝,詳見 Ceph 下載安裝。
# 在主控節點安裝部署工具,需確認其版本為 quincy(17.2.6),這在 Ubuntu 22 已經是預設提供的版本
apt install cephadm
# 如果你的系統 apt 源提供的版本不滿足要求,則需額外手動從 Ceph 官方網站下載
# 比方說 Ubuntu 20(focal),就需要用下方命令手動安裝
# wget https://download.ceph.com/debian-17.2.6/pool/main/c/ceph/cephadm_17.2.6-1focal_amd64.deb
# dpkg -i ./cephadm_17.2.6-1focal_amd64.deb
# 手動安裝完 cephadm 後,還需要額外將 Ceph 相關的軟體源納入到包管理器的 repo 列表
# 該命令是為了下一步能夠安裝版本符合要求的 ceph-common
# cephadm add-repo --release quincy
# 安裝 Ceph 相關的各種工具
apt install ceph-common
初始化叢集,其中 mon-ip
為主控機的內網地址,多網路卡叢集可以額外指定內部網路,比如 --cluster-network 10.90.90.0/24
。
# 命令執行完畢以後,會列印 Ceph Dashboard 的賬號密碼,注意儲存
cephadm --image quay.io/ceph/ceph:v17.2.6-20230920 bootstrap --mon-ip 10.38.0.1 --log-to-file
Ceph 主控程式上線後,會生成自己的金鑰,需要將其安裝到所有節點:
# 列印公鑰,複製內容
cat /etc/ceph/ceph.pub
# 撰寫命令,批次執行
parallel-ssh -h hosts.txt -i 'echo ssh-rsa xxx ceph-xxx >> /root/.ssh/authorized_keys'
公鑰安裝完畢以後,主控節點就能登入所有 worker 節點進行運維操作了。進入 Ceph 管理容器,後續命令都在這個管理容器內執行。但考慮到主控節點已經在宿主機層面安裝了所有需要的工具,事實上不進入 cephadm shell 也是完全可以的。
# 執行該命令以後,會進入容器,但是 prompt 不會有任何變化
cephadm shell
# 可以列印程式,識別當前是在宿主機,還是容器內
ps -ef
確認叢集初始狀態,並進行一系列預調優:
# 檢視叢集狀態
ceph -s
# 禁用掉無用的 nfs 模組
ceph mgr module disable nfs
# 預設每個 OSD 記憶體上限 4G
# 在 Ceph 叢集中,一塊盤(塊裝置)會部署為一個 OSD
# 每節點 8 塊盤,記憶體 256G,因此給與 16G 更大的記憶體上限
# 調整過後,OSD 佔用的記憶體總上限為 128G,還有充足冗餘
ceph config set osd osd_memory_target 17179869184
組建 Ceph 叢集
將所有節點新增進 Ceph 叢集,前 5 臺節點(含主控)打上 _admin 標籤,後續的節點則不需要。考慮到節點眾多,將其撰寫為指令碼執行:
# 主控節點早已是叢集成員,不需要 add
# 因此為 ceph-node[02:04] 新增 _admin 標籤,其他節點則不需要
ceph orch host add ceph-node02 10.32.0.2 --labels _admin
...
ceph orch host add ceph-node16 10.32.0.16
至此,所有節點都已經加入 Ceph 叢集,會自動探測節點下的可用塊裝置,具體而言,未經格式化、無人使用的盤,均會探測到。不必擔心,在執行後續 add osd 前,這個過程不會對盤做任何修改。
# 檢視所有節點可用的盤,確認與現場實際情況匹配,也就是所有的空盤都探測到了、沒有壞盤
ceph orch device ls
# 非新盤需要先格式化
# ceph orch device zap host0 /dev/nvme0n1 --force
# 把所有節點的所有空閒 SSD 都新增為 Ceph OSD
# 執行完這個命令後,盤就歸 Ceph 管理了
# 注意按順序逐個新增以保證 ID 有序,這個過程耗時很長,建議做成指令碼執行
ceph orch daemon add osd ceph-node01:/dev/nvme0n1
ceph orch daemon add osd ceph-node01:/dev/nvme1n1
...
ceph orch daemon add osd ceph-node16:/dev/nvme7n1
# 部署 OSD 過程中,用這個命令檢視進度、狀態
ceph orch ps --daemon_type osd
建立儲存池
所有盤都順利部署為 OSD 後,就可以建立儲存池(pool),然後對接 JuiceFS 檔案系統開始使用了。建立儲存池之前,務必瞭解 Ceph 中支援的兩種儲存模式:
-
副本模式(replication):預設每個物件儲存 3 份(size=3)。與之伴隨的另一個概念叫「最小可用副本數」,預設為 2(min_size=2),意為最少需要 2 個正常執行的副本,才能進行 I/O 操作。可想而知,在預設的 size=3,min_size=2 的配置下,最多允許 1 個副本損壞,這也是最適宜生產環境的設定。如果改為 size=2,min_size=1,那麼所有物件就只有 2 副本,如果任一出現故障,資料將只存一份,丟失的風險增加。副本模式下的故障域也和叢集的配置相關,在節點數 ≧ 3 的情況下,Ceph 會自動將副本分散到不同的節點上,因此對於預設的副本引數,允許任意一臺節點異常而不影響服務。
-
糾刪碼模式(erasure code, EC):相比副本模式提供更好的儲存效率,但糾刪碼本身也帶來一定的計算資源損耗。如果希望優先節約磁碟空間,可以選取該模式;
# 兩個數字是放置組(placement group)個數,需要相同
# 取值公式:num_osd * 100 / 3 並向上取 2 的冪,num_osd 是 128,因此此處取 4096
ceph osd pool create jfsvol 4096 4096 replicated
ceph osd pool application enable jfsvol juicefs
糾刪碼模式的建立命令示範:
# EC 4+2 池(stripe unit 預設是 4K)
# ceph osd erasure-code-profile set jfs-ec k=4 m=2 stripe_unit=8192
# ceph osd pool create ec-pool 32 32 erasure jfs-ec
至此,Ceph 部署完可以投入使用,推薦先跳過下方的監控告警小節,直接對接 JuiceFS 檔案系統。對接完成後,再搭建監控也不遲。
對接 JuiceFS 檔案系統
建立 JuiceFS 檔案系統,Bucket 名稱對齊儲存池名稱,也就是上方建立好的 jfsvol。然後按照文件操作掛載。
在 CSI 驅動中掛載對接了 Ceph 的 JuiceFS 檔案系統,為了讓 Ceph 配置檔案對 JuiceFS 客戶端可見,需要把他們上傳到 Kubernetes Secret:
# 上傳之前,確保配置檔案末尾有換行符,否則後續掛載可能引發異常
echo >> ceph.conf
echo >> ceph.client.admin.keyring
kubectl create secret generic ceph-secret --from-file=ceph.conf=ceph.conf --from-file=ceph.client.admin.keyring=ceph.client.admin.keyring
建立好 Secret 以後,還需要在檔案系統認證資訊裡新增 configs 欄位:
apiVersion: v1
kind: Secret
metadata:
name: jfsvol-secret
type: Opaque
stringData:
name: jfsvol
token: xxx
access-key: ceph
secret-key: client.admin
# 將上方建立的 ceph-secret 掛載到 /etc/ceph
configs: '{"ceph-secret": "/etc/ceph/"}'
運維
Ceph 是很成熟的儲存方案,如果規劃和運維正確,能夠很穩定地執行。閱讀下方小節瞭解常見的運維要點。
部署監控
Cephadm 部署時,會預設安裝自己的 Grafana,並且預設與其 Dashboard 進行了整合。你可以直接使用這個 Dashboard 進行監控告警,也可以選擇對接已有的外部 Grafana。
如果希望複用環境中已有的外部 Grafana,那麼首先瀏覽器開啟這個 Grafana 的地址,點選左側邊欄 Administration,新增資料來源,把 Ceph 叢集的 Prometheus 地址填進去,預設是 http://<ceph-master-ip>:9095
,如果你不確定具體埠號,也可以去主控節點 ss -lntp | grep prometheus
確認現場情況。測試並儲存資料來源。
Prometheus 新增成功後,匯入社群的 Ceph Grafana Dashboard,監控就搭建完畢了,這個 Dashboard 裡已經內建了告警規則,後續配置好告警傳送通道以後,就能直接開始執行。
容量監控和故障恢復
可以方便地用 ceph -s 檢視當前用量,在上一小節中匯入的皮膚裡,也已經包含了容量監控規則,對 Ceph 各個層面的容量佔用進行監控:
-
CephNodeRootFilesystemFull:節點根分割槽用量監控
-
CephOSDNearFull|CephOSDFull|CephOSDBackfillFull:OSD 相關容量監控
-
CephPoolNearFull|CephPoolFull|CephPoolBackfillFull:儲存池相關容量監控
上方報警項中,如果 Ceph 系統寫滿,那麼會觸發 CephOSDFull|CephPoolFull,同時 Ceph 不再允許寫入——這是很不妙的情況,因為對於 Ceph 而言,「刪」事實上也屬於寫請求,在 CephPoolFull 的情況下,即便是客戶端發起刪請求,Ceph 也會進行攔截,讓請求無法完成、直至超時。出現這種故障時,如果無法立刻加盤擴容,那麼處置步驟如下:
- 定位到問題檔案系統,接下來將會清理該檔案系統、釋放容量,因此需要:
-
提前將回收站設定為 0,否則即便刪除了檔案,也會移入回收站進行儲存,無法釋放物件儲存容量
-
推薦在業務側操作下線停寫(考慮到 Ceph 此時已經容量超限,所有的寫請求都會卡死),這並不是必要的,只是為了增加後續運維動作的容錯率
-
選取該檔案系統的一個可用客戶端,進入掛載點,清理檔案、釋放容量。
-
在 JuiceFS 掛載點刪除足量的檔案,如果 Ceph 一側沒有立即釋放容量,則說明遇到了上方提到的「容量超限時,無法執行刪除」的死鎖問題,這時需要登入 Ceph 主控節點,將閾值臨時提高,來允許刪除請求。操作前必須確保業務已經停寫,否則一旦放開閾值,就會迅速寫滿,再次引發故障。
# mon_osd_full_ratio 預設為 0.95,臨時調高以允許寫入
ceph osd set-full-ratio 0.96
# 放開閾值後,緊密觀察容量是否釋放
ceph -s
4. 確認容量釋放,準備回滾 full ratio 設定。這一步也需要謹慎操作:將 full ratio 回滾,必須保證操作不會再次讓叢集處於容量超限的狀態、中斷業務寫入。因此先執行 ceph df 核實已用空間佔比(%USED
)。
如果 %USED
低於 90%,那麼可以執行下方命令回滾配置:
ceph osd set-full-ratio 0.95
為了改善容量超限的處置流程,JuiceFS 客戶端支援在 Ceph 叢集寫滿的情況下進行刪除操作(詳見社群版相關程式碼變更),因此對於新版客戶端,不再需要用 set-full-ratio 進行臨調。
擴容
由於是最為常見的擴容方法,本小節只介紹用增添新盤來擴大叢集容量的操作。
插盤已經在所有節點完成後,執行命令確認新盤:
# 輸出表格里,AVAILABLE=Yes 的即為探測到的新盤
# 確認新盤引數符合預期
ceph orch device ls
在建立新的 OSD 之前,推薦先手動禁用資料均衡。這是由於盤數量可能比較多,OSD 建立需要格式化盤,整個操作耗時會比較長。如果在預設開啟資料遷移的狀態下加盤,每一個新盤都會伴隨著資料遷移。為了避免低效的資料反覆遷移,建議在所有新盤納入 Ceph 後,再統一開啟。
# 禁用資料均衡
ceph osd set nobackfill
# 確認生效
ceph -s | grep backfill
接下來執行命令新增新盤,操作和建立 Ceph 叢集中的相關步驟是完全一樣的,在對應的小節裡搜尋 ceph orch daemon add osd 命令,將所有新盤按順序新增,就可以了。如果待新增的盤數量眾多,建議提前撰寫指令碼執行。
所有盤新增完成後,執行下方命令進行收尾:
# 確認所有新盤均已加入叢集(AVAILABLE=No)
ceph orch device ls
# 重新開啟資料均衡
ceph osd unset nobackfill