淺析 Rook 如何管理 Ceph Cluster
最近做了很多 Rook 的調(diào)研工作,邊學(xué)習(xí)邊梳理清楚了 Rook 如何管理 Ceph 集群。這篇文章就來(lái)講解 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)都會(huì)向 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)保存對(duì)象,并通過(guò)網(wǎng)絡(luò)提供訪問(wèn)。通常 OSD 守護(hù)進(jìn)程會(huì)綁定在集群的一個(gè)物理盤(pán)上;同時(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í)候才會(huì)需要。
Ceph 客戶端首先會(huì)聯(lián)系 Mon,獲取最新的集群地圖,其中包含了集群拓?fù)湟约皵?shù)據(jù)存儲(chǔ)位置的信息。然后使用集群地圖來(lái)獲知需要交互的 OSD,從而和特定 OSD 建立聯(lián)系。
Rook 是一個(gè)提供 Ceph 集群管理能力的 Operator,使用 CRD CephCluster 來(lái)對(duì) Ceph 集群進(jìn)行部署和管理。以下是 Rook 的架構(gòu)圖:
圖片
最下層是 Rook Operator 部署的 Ceph 集群的各種組件,通過(guò) CSI Plugin 向上對(duì)應(yīng)用提供不同的訪問(wèn)接口。
安裝
本文演示使用的所有 Yaml 文件,均來(lái)自 Rook 倉(cāng)庫(kù)的 examples。
安裝 Rook Operator
Rook Operator 的安裝主要分兩部分:RBAC 和 operator deployment,分別在兩個(gè)文件下:
kubectl apply -f common.yaml
kubectl apply -f operator.yaml
安裝完成后可以看到集群里只有一個(gè) operator pod,非常簡(jiǎn)潔:
$ kubectl -n rook-ceph get po
NAME READY STATUS RESTARTS AGE
rook-ceph-operator-7d8898f668-2chvz 1/1 Running 0 2d16h
安裝 CephCluster
Ceph 要求每個(gè)存儲(chǔ)節(jié)點(diǎn)都有一個(gè)塊設(shè)備,建議盡量為所有存儲(chǔ)節(jié)點(diǎn)分配同樣的 CPU、內(nèi)存和磁盤(pán)。
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 寫(xiě):
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 會(huì)安裝一系列 ceph 的組件。首先會(huì)看到以下 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 中通過(guò) nodeSelector 等調(diào)度策略來(lái)決定如何部署 Mon。由于 Mon 使用 hostPath 作為其存儲(chǔ),所以 Mon pod 需要固定在特定的節(jié)點(diǎn)上。但 Kubernetes 無(wú)法做到在 Pod 被調(diào)度后,又自動(dòng)設(shè)置上對(duì)所在節(jié)點(diǎn)的親和性。
Rook 對(duì)這一問(wèn)題的處理方式是,先部署一個(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)度后隨即被刪除,然后開(kāi)始部署 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è)備沒(méi)有分區(qū)
- 設(shè)備沒(méi)有格式化的文件系統(tǒng)
圖片
如果有,才會(huì)進(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 來(lái)檢查 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
訪問(wèn) Ceph
Ceph 提供 3 種訪問(wèn)方式,分別為對(duì)象存儲(chǔ)接口(radosgw)、塊設(shè)備接口(rbd)、文件系統(tǒng)接口(POSIX)。
圖片
其中文件系統(tǒng)接口的訪問(wèn)需要部署元數(shù)據(jù)服務(wù) MDS;rbd 和 fs 都是通過(guò) CSI Driver 的方式提供掛載到應(yīng)用容器內(nèi),也就是前面看到的兩個(gè) CSI Driver。
rgw
rgw 的訪問(wèn)需要 cephobjectstore 這個(gè) CR:
$ kubectl apply -f object.yaml
cephobjectstore.ceph.rook.io/my-store created
隨后可以看到組件 RGW 被創(chuàng)建出來(lái):
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)名稱(chēng)會(huì)顯示 Mon 的連接信息。
總結(jié)
Rook 對(duì) Ceph 的支持遠(yuǎn)不止管理其集群,還包括很多數(shù)據(jù)面的支持,比如對(duì) osd pool 的創(chuàng)建等,還提供了一系列的狀態(tài)管理和查詢。本文只針對(duì) Ceph 集群的創(chuàng)建和管理做了簡(jiǎn)單的分析和梳理,希望對(duì)如何在 Kubernetes 中管理和使用 Ceph 有所幫助。