淺析 Rook 如何管理 Ceph Cluster
最近做了很多 Rook 的調(diào)研工作,邊學(xué)習(xí)邊梳理清楚了 Rook 如何管理 Ceph 集群。這篇文章就來講解 Rook 如何將 Ceph 這么復(fù)雜的系統(tǒng)在 Kubernetes 中進(jìn)行管理和維護(hù)。
Ceph 的架構(gòu)
Ceph 包括多個(gè)組件:
- Ceph Monitors(Mon):負(fù)責(zé)監(jiān)控集群的全局狀態(tài),包括集群的配置信息和數(shù)據(jù)的映射關(guān)系,所有的集群節(jié)點(diǎn)都會向 Mon 進(jìn)行匯報(bào),并在每次狀態(tài)變更時(shí)進(jìn)行共享信息;負(fù)責(zé)管理集群的內(nèi)部狀態(tài),包括 OSD 故障后的恢復(fù)工作和數(shù)據(jù)的恢復(fù);以及客戶端的查詢和授權(quán)工作。
- Ceph Object Store Devices(OSD):負(fù)責(zé)在本地文件系統(tǒng)保存對象,并通過網(wǎng)絡(luò)提供訪問。通常 OSD 守護(hù)進(jìn)程會綁定在集群的一個(gè)物理盤上;同時(shí)負(fù)責(zé)監(jiān)控本身以及其他 OSD 進(jìn)程的健康狀態(tài)并匯報(bào)給 Mon。
- Ceph Manager(MGR):提供額外的監(jiān)控和界面給外部的監(jiān)管系統(tǒng)使用。
- Ceph Metadata Server(MDS):CephFS 的元數(shù)據(jù)管理進(jìn)程,主要負(fù)責(zé)文件系統(tǒng)的元數(shù)據(jù)管理,只有需要使用 CephFS 的時(shí)候才會需要。
Ceph 客戶端首先會聯(lián)系 Mon,獲取最新的集群地圖,其中包含了集群拓?fù)湟约皵?shù)據(jù)存儲位置的信息。然后使用集群地圖來獲知需要交互的 OSD,從而和特定 OSD 建立聯(lián)系。
Rook 是一個(gè)提供 Ceph 集群管理能力的 Operator,使用 CRD CephCluster 來對 Ceph 集群進(jìn)行部署和管理。以下是 Rook 的架構(gòu)圖:
圖片
最下層是 Rook Operator 部署的 Ceph 集群的各種組件,通過 CSI Plugin 向上對應(yīng)用提供不同的訪問接口。
安裝
本文演示使用的所有 Yaml 文件,均來自 Rook 倉庫的 examples。
安裝 Rook Operator
Rook Operator 的安裝主要分兩部分:RBAC 和 operator deployment,分別在兩個(gè)文件下:
kubectl apply -f common.yaml
kubectl apply -f operator.yaml
安裝完成后可以看到集群里只有一個(gè) operator pod,非常簡潔:
$ kubectl -n rook-ceph get po
NAME READY STATUS RESTARTS AGE
rook-ceph-operator-7d8898f668-2chvz 1/1 Running 0 2d16h
安裝 CephCluster
Ceph 要求每個(gè)存儲節(jié)點(diǎn)都有一個(gè)塊設(shè)備,建議盡量為所有存儲節(jié)點(diǎn)分配同樣的 CPU、內(nèi)存和磁盤。
Rook 的 examples 下提供了一個(gè)默認(rèn)配置的 CephCluster 文件 cluster.yaml,在 storage 中可以使用正則表達(dá)式 /dev/sd[a-z] 進(jìn)行設(shè)備匹配:
storage:
useAllNodes: true
useAllDevices: false
deviceFilter: sd[a-z]
如果節(jié)點(diǎn)異構(gòu),也可以分 node 寫:
storage:
useAllNodes: true
useAllDevices: false
nodes:
- name: "172.17.4.201"
devices:
- name: "sdb"
- name: "nvme01"
- name: "172.17.4.301"
deviceFilter: "^sd."
創(chuàng)建了 CephCluster,隨后 operator 會安裝一系列 ceph 的組件。首先會看到以下 pod:
NAME READY STATUS RESTARTS AGE
csi-cephfsplugin-provisioner-868bf46b56-4xkx4 5/5 Running 0 3s
csi-cephfsplugin-provisioner-868bf46b56-qsxkg 5/5 Running 0 3s
csi-cephfsplugin-4jrsn 2/2 Running 0 3s
csi-cephfsplugin-wfzmm 2/2 Running 0 3s
csi-cephfsplugin-znn9x 2/2 Running 0 3s
csi-rbdplugin-6x94s 2/2 Running 0 3s
csi-rbdplugin-8cmfw 2/2 Running 0 3s
csi-rbdplugin-qm8jr 2/2 Running 0 3s
csi-rbdplugin-provisioner-d9b9d694c-s7vxg 5/5 Running 0 3s
csi-rbdplugin-provisioner-d9b9d694c-tlplc 5/5 Running 0 3s
rook-ceph-mon-a-canary-ddb95876f-wl26c 0/2 ContainerCreating 0 0s
rook-ceph-mon-b-canary-57dc9df878-7ntq9 0/2 ContainerCreating 0 0s
rook-ceph-mon-c-canary-685fdfb595-6cxjj 0/2 ContainerCreating 0 0s
主要有 cephfs 和 rbd 的相關(guān) CSI Driver 組件,以及 Mon canary。
Mon canary 是將 Ceph 的 Mon 組件的 command 改成 sleep 3600,并按 cluster 中指定的 placement 等調(diào)度信息進(jìn)行合并后的 Deployment。
管理員可以在 Cluster 中通過 nodeSelector 等調(diào)度策略來決定如何部署 Mon。由于 Mon 使用 hostPath 作為其存儲,所以 Mon pod 需要固定在特定的節(jié)點(diǎn)上。但 Kubernetes 無法做到在 Pod 被調(diào)度后,又自動設(shè)置上對所在節(jié)點(diǎn)的親和性。
Rook 對這一問題的處理方式是,先部署一個(gè)相同配置的 Mon canary Deployment,任由調(diào)度器按照 cluster 中設(shè)置的調(diào)度策略部署 canary pod。再按照調(diào)度有 canary pod 的節(jié)點(diǎn),部署一個(gè) Mon deployment,其 nodeSelector 為 kubernetes.io/hostname:<nodeName>,從而實(shí)現(xiàn)將 Mon 固定在節(jié)點(diǎn)上。
圖片
在 Mon cacnary 完成調(diào)度后隨即被刪除,然后開始部署 Monitor 組件,以及相關(guān)的 Mon Manager、CrashController 及 exporter:
NAME READY STATUS RESTARTS AGE
rook-ceph-crashcollector-cn-hongkong.192.168.0.55-66586f572zcg6 1/1 Running 0 15s
rook-ceph-crashcollector-cn-hongkong.192.168.0.56-748b6785dk7wl 1/1 Running 0 7s
rook-ceph-crashcollector-cn-hongkong.192.168.0.57-68774ff8hz42l 1/1 Running 0 15s
rook-ceph-exporter-cn-hongkong.192.168.0.55-789684674-26vwv 1/1 Running 0 15s
rook-ceph-exporter-cn-hongkong.192.168.0.56-694f674bdc-z9znh 1/1 Running 0 7s
rook-ceph-exporter-cn-hongkong.192.168.0.57-bbf8db8c6-2zjbq 1/1 Running 0 15s
rook-ceph-mgr-a-6c4b684b9f-4dx79 2/3 Running 0 15s
rook-ceph-mgr-b-75d5658884-pmq99 2/3 Running 0 15s
rook-ceph-mon-a-5c5dbf577c-2bssb 2/2 Running 0 61s
rook-ceph-mon-b-8d8c56989-g7znk 2/2 Running 0 37s
rook-ceph-mon-c-6677fc9f7c-slhvj 2/2 Running 0 26s
當(dāng) Monitor 部署成功后,operator 為 OSD 做準(zhǔn)備,在每個(gè)數(shù)據(jù)節(jié)點(diǎn)創(chuàng)建一個(gè) Job,查詢每個(gè)節(jié)點(diǎn)上是否存在滿足以下條件的設(shè)備:
- 設(shè)備沒有分區(qū)
- 設(shè)備沒有格式化的文件系統(tǒng)
圖片
如果有,才會進(jìn)入下一步部署 OSD 的階段。
NAME READY STATUS RESTARTS AGE
rook-ceph-osd-prepare-cn-hongkong.192.168.0.55-9fq2t 0/1 Completed 0 11s
rook-ceph-osd-prepare-cn-hongkong.192.168.0.56-bdptk 0/1 Completed 0 11s
rook-ceph-osd-prepare-cn-hongkong.192.168.0.57-7f7bx 0/1 Completed 0 10s
圖片
在滿足條件的節(jié)點(diǎn)上創(chuàng)建 OSD:
NAME READY STATUS RESTARTS AGE
rook-ceph-osd-0-5bbb5d965f-k8k7z 1/2 Running 0 17s
rook-ceph-osd-1-56b689549b-8gj47 1/2 Running 0 16s
rook-ceph-osd-2-5946f9684f-wkwmm 1/2 Running 0 16s
至此,整個(gè) Ceph Cluster 算是安裝完成了,除了查看各個(gè)組件是否 ready 外,還可以使用 Rook 提供的 Ceph Tool 來檢查 Ceph 集群是否 work。安裝 Ceph Tool:
kubectl apply -f toolbox.yaml
在 tool pod 中檢查集群狀態(tài),在輸出中不僅可以可以查看當(dāng)前 ceph 集群是否健康,還可以查看各個(gè)組件的個(gè)數(shù)及狀態(tài):
bash-4.4$ ceph status
cluster:
id: 0212449b-1184-43ff-9d24-e6765d75ac3f
health: HEALTH_OK
services:
mon: 3 daemons, quorum a,b,c (age 7m)
mgr: a(active, since 5m), standbys: b
osd: 3 osds: 3 up (since 6m), 3 in (since 6m)
data:
pools: 1 pools, 1 pgs
objects: 2 objects, 449 KiB
usage: 80 MiB used, 60 GiB / 60 GiB avail
pgs: 1 active+clean
訪問 Ceph
Ceph 提供 3 種訪問方式,分別為對象存儲接口(radosgw)、塊設(shè)備接口(rbd)、文件系統(tǒng)接口(POSIX)。
圖片
其中文件系統(tǒng)接口的訪問需要部署元數(shù)據(jù)服務(wù) MDS;rbd 和 fs 都是通過 CSI Driver 的方式提供掛載到應(yīng)用容器內(nèi),也就是前面看到的兩個(gè) CSI Driver。
rgw
rgw 的訪問需要 cephobjectstore 這個(gè) CR:
$ kubectl apply -f object.yaml
cephobjectstore.ceph.rook.io/my-store created
隨后可以看到組件 RGW 被創(chuàng)建出來:
NAME READY STATUS RESTARTS AGE
rook-ceph-rgw-my-store-a-6f6768f457-tq625 1/2 Running 0 33s
檢查集群狀態(tài),可以觀察到 RGW:
bash-4.4$ ceph status
cluster:
id: 0212449b-1184-43ff-9d24-e6765d75ac3f
health: HEALTH_OK
services:
mon: 3 daemons, quorum a,b,c (age 11m)
mgr: a(active, since 10m), standbys: b
mds: 1/1 daemons up, 1 hot standby
osd: 3 osds: 3 up (since 11m), 3 in (since 4d)
rgw: 1 daemon active (1 hosts, 1 zones)
...
具體使用可以參考 Rook 官方文檔
rbd
rbd 接口需要?jiǎng)?chuàng)建 replicapool 這個(gè) CR 和 rbd 的 StorageClass:
$ kubectl apply -f csi/rbd/storageclass.yaml
cephblockpool.ceph.rook.io/replicapool created
storageclass.storage.k8s.io/rook-ceph-block created
再創(chuàng)建應(yīng)用 pod 和 pvc:
kubectl apply -f csi/rbd/pvc.yaml
kubectl apply -f csi/rbd/pod.yaml
上述資源都創(chuàng)建完畢后,進(jìn)入示例 pod 中可查看其中的掛載設(shè)備:
$ kubectl exec -it csirbd-demo-pod -- bash
root@csirbd-demo-pod:/#
root@csirbd-demo-pod:/#
root@csirbd-demo-pod:/# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
...
rbd0 252:0 0 1G 0 disk /var/lib/www/html
vda 253:0 0 120G 0 disk
|-vda1 253:1 0 2M 0 part
|-vda2 253:2 0 200M 0 part
`-vda3 253:3 0 119.8G 0 part
filesystem
fs 接口需要?jiǎng)?chuàng)建 cephfilesystem 和 cephfilesystemsubvolumegroup 兩個(gè) CR:
$ kubectl apply -f filesystem.yaml
cephfilesystem.ceph.rook.io/myfs created
cephfilesystemsubvolumegroup.ceph.rook.io/myfs-csi created
創(chuàng)建完畢后,可以觀察集群中已經(jīng)創(chuàng)建出元數(shù)據(jù)服務(wù) MDS:
NAME READY STATUS RESTARTS AGE
rook-ceph-mds-myfs-a-9d8c6b7f8-f84pm 2/2 Running 0 17s
rook-ceph-mds-myfs-b-dff454bf6-wxln6 2/2 Running 0 16s
這時(shí)在 tool pod 中查看集群狀態(tài),可以看到 mds 的狀態(tài):
bash-4.4$ ceph status
cluster:
id: 0212449b-1184-43ff-9d24-e6765d75ac3f
health: HEALTH_OK
services:
mon: 3 daemons, quorum a,b,c (age 13m)
mgr: a(active, since 12m), standbys: b
mds: 1/1 daemons up, 1 hot standby
osd: 3 osds: 3 up (since 13m), 3 in (since 13m)
...
最后部署 StorageClass 、PVC 以及示例應(yīng)用 pod:
$ kubectl apply -f csi/cephfs/storageclass.yaml
storageclass.storage.k8s.io/rook-cephfs created
$ kubectl apply -f csi/cephfs/pvc.yaml
persistentvolumeclaim/cephfs-pvc created
$ kubectl apply -f csi/cephfs/pod.yaml
pod/csicephfs-demo-pod created
進(jìn)入 pod 查看文件系統(tǒng)掛載點(diǎn):
$ kubectl exec -it csicephfs-demo-pod -- bash
root@csicephfs-demo-pod:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 20G 9.9G 8.4G 54% /
tmpfs 64M 0 64M 0% /dev
tmpfs 16G 0 16G 0% /sys/fs/cgroup
/dev/vdb 20G 9.9G 8.4G 54% /etc/hosts
shm 64M 0 64M 0% /dev/shm
172.16.233.104:6789,172.16.38.236:6789,172.16.112.253:6789:/volumes/csi/csi-vol-37584a87-0dfb-48f2-8eee-647af351a695/fc5823e6-0c7e-4ce3-8565-4429d366ac64 1.0G 0 1.0G 0% /var/lib/www/html
tmpfs 30G 12K 30G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 16G 0 16G 0% /proc/acpi
tmpfs 16G 0 16G 0% /proc/scsi
tmpfs 16G 0 16G 0% /sys/firmware
Ceph 的掛載點(diǎn)名稱會顯示 Mon 的連接信息。
總結(jié)
Rook 對 Ceph 的支持遠(yuǎn)不止管理其集群,還包括很多數(shù)據(jù)面的支持,比如對 osd pool 的創(chuàng)建等,還提供了一系列的狀態(tài)管理和查詢。本文只針對 Ceph 集群的創(chuàng)建和管理做了簡單的分析和梳理,希望對如何在 Kubernetes 中管理和使用 Ceph 有所幫助。