在 Kubernetes 生態系統中,持久化儲存是支撐業務應用穩定執行的基石,對於維護整個系統的健壯性至關重要。對於選擇自主搭建 Kubernetes 叢集的運維架構師來說,挑選合適的後端持久化儲存解決方案是關鍵的選型決策。目前,Ceph、GlusterFS、NFS、Longhorn 和 openEBS 等解決方案已在業界得到廣泛應用。
為了豐富技術棧,併為容器雲平臺的持久化儲存設計提供更廣泛的靈活性和選擇性,今天,我將帶領大家一起探索,如何將 Ceph 整合到由 KubeSphere 管理的 Kubernetes 叢集中。
整合 Ceph 至 Kubernetes 叢集主要有兩種方案:
- 利用 Rook Ceph 直接在 Kubernetes 叢集上部署 Ceph 叢集,這種方式更貼近雲原生的應用特性。
- 手動部署獨立的 Ceph 叢集,並配置 Kubernetes 叢集與之對接,實現儲存服務的整合。
本文將重點實戰演示使用 Rook Ceph 在 Kubernetes 叢集上直接部署 Ceph 叢集的方法,讓您體驗到雲原生環境下 Ceph 部署的便捷與強大。
實戰伺服器配置(架構 1:1 復刻小規模生產環境,配置略有不同)
主機名 | IP | CPU | 記憶體 | 系統盤 | 資料盤 | 用途 |
---|---|---|---|---|---|---|
ksp-registry | 192.168.9.90 | 4 | 8 | 40 | 200 | Harbor 映象倉庫 |
ksp-control-1 | 192.168.9.91 | 4 | 8 | 40 | 100 | KubeSphere/k8s-control-plane |
ksp-control-2 | 192.168.9.92 | 4 | 8 | 40 | 100 | KubeSphere/k8s-control-plane |
ksp-control-3 | 192.168.9.93 | 4 | 8 | 40 | 100 | KubeSphere/k8s-control-plane |
ksp-worker-1 | 192.168.9.94 | 4 | 16 | 40 | 100 | k8s-worker/CI |
ksp-worker-2 | 192.168.9.95 | 4 | 16 | 40 | 100 | k8s-worker |
ksp-worker-3 | 192.168.9.96 | 4 | 16 | 40 | 100 | k8s-worker |
ksp-storage-1 | 192.168.9.97 | 4 | 8 | 40 | 400+ | Containerd、OpenEBS、ElasticSearch/Longhorn/Ceph/NFS |
ksp-storage-2 | 192.168.9.98 | 4 | 8 | 40 | 300+ | Containerd、OpenEBS、ElasticSearch/Longhorn/Ceph |
ksp-storage-3 | 192.168.9.99 | 4 | 8 | 40 | 300+ | Containerd、OpenEBS、ElasticSearch/Longhorn/Ceph |
ksp-gpu-worker-1 | 192.168.9.101 | 4 | 16 | 40 | 100 | k8s-worker(GPU NVIDIA Tesla M40 24G) |
ksp-gpu-worker-2 | 192.168.9.102 | 4 | 16 | 40 | 100 | k8s-worker(GPU NVIDIA Tesla P100 16G) |
ksp-gateway-1 | 192.168.9.103 | 2 | 4 | 40 | 自建應用服務代理閘道器/VIP:192.168.9.100 | |
ksp-gateway-2 | 192.168.9.104 | 2 | 4 | 40 | 自建應用服務代理閘道器/VIP:192.168.9.100 | |
ksp-mid | 192.168.9.105 | 4 | 8 | 40 | 100 | 部署在 k8s 叢集之外的服務節點(Gitlab 等) |
合計 | 15 | 56 | 152 | 600 | 2100+ |
實戰環境涉及軟體版本資訊
- 作業系統:openEuler 22.03 LTS SP3 x86_64
- KubeSphere:v3.4.1
- Kubernetes:v1.28.8
- KubeKey: v3.1.1
- Containerd:1.7.13
- Rook:v1.14.9
- Ceph: v18.2.4
1. Rook 部署規劃
為了更好地滿足生產環境的實際需求,在規劃和部署儲存基礎設施時,我增加了以下策略:
- 節點擴充套件:向 Kubernetes 叢集中新增三個專用節點,這些節點將專門承載 Ceph 儲存服務,確儲存儲操作的高效性和穩定性。
- 元件隔離:所有 Rook 和 Ceph 元件以及資料卷將被部署在這些專屬節點上,實現元件的清晰隔離和專業化管理。
- 節點標籤化:為每個儲存節點設定了專門的標籤
node.kubernetes.io/storage=rook
,以便 Kubernetes 能夠智慧地排程相關資源。同時,非儲存節點將被標記為node.rook.io/rook-csi=true
,這表明它們將承載 Ceph CSI 外掛,使得執行在這些節點上的業務 Pod 能夠利用 Ceph 提供的持久化儲存。 - 儲存介質配置:在每個儲存節點上,我將新增一塊 100G 的 Ceph 專用資料盤
/dev/sdd
。為保證最佳效能,該磁碟將採用裸裝置形態直接供 Ceph OSD 使用,無需進行分割槽或格式化。
重要提示:
- 本文提供的配置和部署經驗對於理解 Rook-Ceph 的安裝和執行機制具有參考價值。然而,強烈建議不要將本文描述的配置直接應用於任何形式的生產環境。
- 在生產環境中,還需進一步考慮使用 SSD、NVMe 磁碟等高效能儲存介質;細緻規劃故障域;制定詳盡的儲存節點策略;以及進行細緻的系統最佳化配置等。
2. 前置條件
2.1 Kubernetes 版本
-
Rook 可以安裝在任何現有的 Kubernetes 叢集上,只要它滿足最低版本,並且授予 Rook 所需的特權
-
早期 v1.9.7 版本的 Rook 支援 Kubernetes v1.17 或更高版本
-
現在的 v1.14.9 版本支援 Kubernetes v1.25 到 v1.30 版本(可能支援更低的版本,可以自己驗證測試)
2.2 CPU Architecture
支援的 CPU 架構包括: amd64 / x86_64
and arm64
。
2.3 Ceph 先決條件
為了配置 Ceph 儲存叢集,至少需要以下任意一種型別的本地儲存:
- Raw devices (no partitions or formatted filesystems,沒有分割槽和格式化檔案系統,本文選擇)
- Raw partitions (no formatted filesystem,已分割槽但是沒有格式化檔案系統)
- LVM Logical Volumes (no formatted filesystem)
- PVs available from a storage class in
block
mode
使用以下命令確認分割槽或裝置是否使用檔案系統並進行了格式化:
$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1 ext4 1.0 b5e46d67-426b-476f-bd89-18137af7ff59 682.5M 23% /boot
└─sda2 LVM2_member LVM2 001 NepB96-M3ux-Ei6Q-V7AX-BCy1-e2RN-Lzbecn
├─openeuler-root ext4 1.0 0495bb1d-16f7-4156-ab10-5bd837b24de5 29.9G 7% /
└─openeuler-swap swap 1 837d3a7e-8aac-4048-bb7a-a6fdd8eb5931
sdb LVM2_member LVM2 001 Dyj93O-8zKr-HMah-hxjd-8IZP-IxVE-riWf3O
└─data-lvdata xfs 1e9b612f-dbd9-46d2-996e-db74073d6648 86G 14% /data
sdc LVM2_member LVM2 001 LkTCe2-0vp7-e3SJ-Xxzb-UzN1-sd2T-74TF3L
└─longhorn-data xfs 30a13ac0-6eef-433c-8d7e-d6776ec669ff 99.1G 1% /longhorn
sdd
- 如果 FSTYPE 欄位不為空,說明該裝置已經格式化為檔案系統,對應的值就是檔案系統型別
- 如果 FSTYPE 欄位為空,說明該裝置還沒有被格式化,可以被 Ceph 使用
- 本例中可以使用的裝置為 sdd
如果需要清理已有磁碟給 Ceph 使用,請使用下面的命令(生產環境請謹慎):
yum install gdisk
sgdisk --zap-all /dev/sdd
2.4 LVM 需求
Ceph OSDs 在以下場景依賴 LVM。
- If encryption is enabled (
encryptedDevice: "true"
in the cluster CR) - A
metadata
device is specified osdsPerDevice
is greater than 1
Ceph OSDs 在以下場景不需要 LVM。
- OSDs are created on raw devices or partitions
- Creating OSDs on PVCs using the
storageClassDeviceSets
openEuler 預設已經安裝 lvm2,如果沒有裝,使用下面的命令安裝。
yum install -y lvm2
2.5 Kernel 需求
- RBD 需求
Ceph 需要使用構建了 RBD 模組的 Linux 核心。許多 Linux 發行版都有這個模組,但不是所有發行版都有。例如,GKE Container-Optimised OS (COS) 就沒有 RBD。
在 Kubernetes 節點使用 lsmod | grep rbd
命令驗證,如果沒有任何輸出,請執行下面的命令載入 rbd 模組。
# 在當前環境載入 rbd 和 nbd 模組
modprobe rbd
modprobe nbd
# 開機自動載入 rbd 和 nbd 模式(適用於 openEuler)
echo "rbd" >> /etc/modules-load.d/rook-ceph.conf
echo "nbd" >> /etc/modules-load.d/rook-ceph.conf
# 再次執行命令驗證
lsmod | grep rbd
# 正確的輸出結果如下
$ lsmod | grep rbd
rbd 135168 0
libceph 413696 1 rbd
- CephFS 需求
如果您將從 Ceph shared file system (CephFS) 建立卷,推薦的最低核心版本是 4.17。如果核心版本小於 4.17,則不會強制執行請求的 PVC sizes。儲存配額只會在更新的核心上執行。
注意: openEuler 22.03 SP3 目前最新的核心為 5.10.0-218.0.0.121
,雖然大於 4.17 但是有些過於高了,在安裝 Ceph CSI Plugin 的時候可能會遇到 CSI 驅動無法註冊的問題。
3. 擴容叢集節點
3.1 擴容儲存專用 Worker 節點
將新增的三臺儲存專用節點加入已有的 Kubernetes 叢集,詳細的擴容操作請參考 KubeKey 擴容 Kubernetes Worker 節點實戰指南。
3.2 設定節點標籤
按規劃給三個儲存節點和其它 Worker 節點打上專屬標籤。
- 儲存節點標籤
# 設定 rook-ceph 部署和儲存Osd 節點標籤
kubectl label nodes ksp-storage-1 node.kubernetes.io/storage=rook
kubectl label nodes ksp-storage-2 node.kubernetes.io/storage=rook
kubectl label nodes ksp-storage-3 node.kubernetes.io/storage=rook
- Worker 節點標籤
# 安裝 ceph csi plugin 節點
# kubectl label nodes ksp-control-1 node.rook.io/rook-csi=true
# kubectl label nodes ksp-control-2 node.rook.io/rook-csi=true
# kubectl label nodes ksp-control-3 node.rook.io/rook-csi=true
kubectl label nodes ksp-worker-1 node.rook.io/rook-csi=true
kubectl label nodes ksp-worker-2 node.rook.io/rook-csi=true
kubectl label nodes ksp-worker-3 node.rook.io/rook-csi=true
- 控制(Control)節點
不做任何設定,Ceph 的服務元件和 CSI 外掛都不會安裝在控制節點。網上也有人建議把 Ceph 的管理元件部署在 K8s 的控制節點,我是不贊同的。個人建議把 Ceph 的所有元件獨立部署。
4. 安裝配置 Rook Ceph Operator
4.1 下載部署程式碼
# git clone --single-branch --branch v1.14.9 https://github.com/rook/rook.git
cd /srv
wget https://github.com/rook/rook/archive/refs/tags/v1.14.9.tar.gz
tar xvf v1.14.9.tar.gz
cd rook-1.14.9/deploy/examples/
4.2 修改映象地址
可選配置,當 DockerHub 訪問受限時,可以將 Rook-Ceph 需要的映象離線下載到本地倉庫,部署時修改映象地址。
# 取消映象註釋
sed -i '125,130s/^.*#/ /g' operator.yaml
sed -i '506,506s/^.*#/ /g' operator.yaml
# 替換映象地址字首
sed -i 's#registry.k8s.io#registry.opsxlab.cn:8443/k8sio#g' operator.yaml
sed -i 's#quay.io#registry.opsxlab.cn:8443/quayio#g' operator.yaml
sed -i 's#rook/ceph:v1.14.9#registry.opsxlab.cn:8443/rook/ceph:v1.14.9#g' operator.yaml
sed -i '24,24s#quay.io#registry.opsxlab.cn:8443/quayio#g' cluster.yaml
注意:上面的映象倉庫是我內部離線倉庫,參考我文件的讀者不要直接照抄,一定要換成自己的映象倉庫。
4.3 修改自定義配置
修改配置檔案 operator.yaml
實現以下需求:
- rook-ceph 所有管理元件部署在指定標籤節點
- k8s 其他節點安裝 Ceph CSI Plugin
CSI_PROVISIONER_NODE_AFFINITY: "node.kubernetes.io/storage=rook"
CSI_PLUGIN_NODE_AFFINITY: "node.rook.io/rook-csi=true,node.kubernetes.io/storage=rook"
4.4 部署 Rook Operator
- 部署 Rook operator
kubectl create -f crds.yaml -f common.yaml -f operator.yaml
- 驗證
rook-ceph-operator
Pod 的狀態是否為Running
kubectl -n rook-ceph get pod -o wide
執行成功後,輸出結果如下:
$ kubectl -n rook-ceph get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rook-ceph-operator-9bd897ff8-426mq 1/1 Running 0 40s 10.233.77.255 ksp-storage-3 <none> <none>
4.5 KubeSphere 控制檯檢視 Operator 資源
登入 KubeSphere 控制檯檢視建立的 Rook Ceph Operator Deployment 資源。
5. 建立 Ceph 叢集
5.1 修改叢集配置檔案
- 修改叢集配置檔案
cluster.yaml
,增加節點親和配置
placement:
all:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node.kubernetes.io/storage
operator: In
values:
- rook
- 修改叢集配置檔案
cluster.yaml
,增加儲存節點和 OSD 磁碟配置
storage: # cluster level storage configuration and selection
useAllNodes: false # 生產環境,一定要修改,預設會使用所有節點
useAllDevices: false # 生產環境,一定要修改,預設會使用所有磁碟
#deviceFilter:
config:
storeType: bluestore
nodes:
- name: "ksp-storage-1"
devices:
- name: "sdd"
- name: "ksp-storage-2"
devices:
- name: "sdd"
- name: "ksp-storage-3"
devices:
- name: "sdd"
5.2 建立 Ceph 叢集
- 建立叢集
kubectl create -f cluster.yaml
- 檢視資源狀態,確保所有相關 Pod 均為
Running
$ kubectl -n rook-ceph get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
csi-cephfsplugin-5mrxf 2/2 Running 0 2m25s 192.168.9.96 ksp-worker-3 <none> <none>
csi-cephfsplugin-5s4kz 2/2 Running 0 2m25s 192.168.9.95 ksp-worker-2 <none> <none>
csi-cephfsplugin-kgd48 2/2 Running 0 2m25s 192.168.9.94 ksp-worker-1 <none> <none>
csi-cephfsplugin-provisioner-7f595d6cc4-5xpm8 5/5 Running 0 2m25s 10.233.64.1 ksp-storage-1 <none> <none>
csi-cephfsplugin-provisioner-7f595d6cc4-q7q4v 5/5 Running 0 2m25s 10.233.77.26 ksp-storage-3 <none> <none>
csi-cephfsplugin-q7rqj 2/2 Running 0 2m25s 192.168.9.97 ksp-storage-1 <none> <none>
csi-cephfsplugin-x6tfj 2/2 Running 0 2m25s 192.168.9.99 ksp-storage-3 <none> <none>
csi-cephfsplugin-z72tl 2/2 Running 0 2m25s 192.168.9.98 ksp-storage-2 <none> <none>
csi-rbdplugin-2f8db 2/2 Running 0 2m25s 192.168.9.97 ksp-storage-1 <none> <none>
csi-rbdplugin-6dtwt 2/2 Running 0 2m25s 192.168.9.94 ksp-worker-1 <none> <none>
csi-rbdplugin-82jrf 2/2 Running 0 2m25s 192.168.9.95 ksp-worker-2 <none> <none>
csi-rbdplugin-dslkj 2/2 Running 0 2m25s 192.168.9.96 ksp-worker-3 <none> <none>
csi-rbdplugin-gjmmw 2/2 Running 0 2m25s 192.168.9.98 ksp-storage-2 <none> <none>
csi-rbdplugin-hfv4k 2/2 Running 0 2m25s 192.168.9.99 ksp-storage-3 <none> <none>
csi-rbdplugin-provisioner-c845669bc-dp6q4 5/5 Running 0 2m25s 10.233.64.4 ksp-storage-1 <none> <none>
csi-rbdplugin-provisioner-c845669bc-f2s6n 5/5 Running 0 2m25s 10.233.77.24 ksp-storage-3 <none> <none>
rook-ceph-crashcollector-ksp-storage-1-7b4cf6c8fb-7s85r 1/1 Running 0 68s 10.233.64.7 ksp-storage-1 <none> <none>
rook-ceph-crashcollector-ksp-storage-2-cc76b86dc-vb4gl 1/1 Running 0 53s 10.233.73.85 ksp-storage-2 <none> <none>
rook-ceph-crashcollector-ksp-storage-3-67bf8cf566-6rcjg 1/1 Running 0 52s 10.233.77.39 ksp-storage-3 <none> <none>
rook-ceph-exporter-ksp-storage-1-646fb48465-5mfcx 1/1 Running 0 68s 10.233.64.14 ksp-storage-1 <none> <none>
rook-ceph-exporter-ksp-storage-2-79fd64549d-rbcnt 1/1 Running 0 50s 10.233.73.86 ksp-storage-2 <none> <none>
rook-ceph-exporter-ksp-storage-3-7877646d8c-7h2wc 1/1 Running 0 48s 10.233.77.32 ksp-storage-3 <none> <none>
rook-ceph-mgr-a-c89b4f8bd-psdwl 3/3 Running 0 86s 10.233.73.80 ksp-storage-2 <none> <none>
rook-ceph-mgr-b-7ffd8dcb85-jpj5x 3/3 Running 0 86s 10.233.77.29 ksp-storage-3 <none> <none>
rook-ceph-mon-a-654b4f677-fmqhx 2/2 Running 0 2m15s 10.233.73.79 ksp-storage-2 <none> <none>
rook-ceph-mon-b-74887d5b9c-4mb62 2/2 Running 0 109s 10.233.77.28 ksp-storage-3 <none> <none>
rook-ceph-mon-c-5fb5489c58-7hj6n 2/2 Running 0 99s 10.233.64.16 ksp-storage-1 <none> <none>
rook-ceph-operator-9bd897ff8-6z45z 1/1 Running 0 29m 10.233.77.18 ksp-storage-3 <none> <none>
rook-ceph-osd-0-65ccb887ff-bjtbs 2/2 Running 0 54s 10.233.64.19 ksp-storage-1 <none> <none>
rook-ceph-osd-1-c689d9f57-x6prx 2/2 Running 0 53s 10.233.73.84 ksp-storage-2 <none> <none>
rook-ceph-osd-2-776bb9cbd6-vmxxp 2/2 Running 0 52s 10.233.77.37 ksp-storage-3 <none> <none>
rook-ceph-osd-prepare-ksp-storage-1-tj6rk 0/1 Completed 0 64s 10.233.64.18 ksp-storage-1 <none> <none>
rook-ceph-osd-prepare-ksp-storage-2-rds4q 0/1 Completed 0 63s 10.233.73.83 ksp-storage-2 <none> <none>
rook-ceph-osd-prepare-ksp-storage-3-hpzgs 0/1 Completed 0 63s 10.233.77.41 ksp-storage-3 <none> <none>
5.3 KubeSphere 控制檯檢視 Ceph 叢集資源
- Deployment(部署,17個)
- Daemonsets(守護程序集,2個)
6. 建立 Rook toolbox
透過 Rook 提供的 toolbox,我們可以實現對 Ceph 叢集的管理。
6.1 建立 toolbox
- 建立 toolbox
kubectl apply -f toolbox.yaml
- 等待 toolbox pod 下載容器映象,並進入 Running 狀態:
kubectl -n rook-ceph rollout status deploy/rook-ceph-tools
6.2 常用命令
- 登入 Toolbox
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
- 驗證 Ceph 叢集狀態
$ kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
bash-5.1$ ceph -s
cluster:
id: e7913148-d29f-46fa-87a6-1c38ddb1530a
health: HEALTH_OK
services:
mon: 3 daemons, quorum a,b,c (age 6m)
mgr: a(active, since 5m), standbys: b
osd: 3 osds: 3 up (since 5m), 3 in (since 5m)
data:
pools: 1 pools, 1 pgs
objects: 2 objects, 577 KiB
usage: 81 MiB used, 300 GiB / 300 GiB avail
pgs: 1 active+clean
觀察 Ceph 叢集狀態,需要滿足下面的條件才會認為叢集狀態是健康的。
- health 的值為 HEALTH_OK
- Mons 的數量和狀態
- Mgr 一個 active,一個 standbys
- OSD 3 個,狀態都是 up
- 其他常用的 Ceph 命令
# 檢視 OSD 狀態
ceph osd status
ceph osd df
ceph osd utilization
ceph osd pool stats
ceph osd tree
# 檢視 Ceph 容量
ceph df
# 檢視 Rados 狀態
rados df
# 檢視 PG 狀態
ceph pg stat
- 刪除 toolbox(可選)
kubectl -n rook-ceph delete deploy/rook-ceph-tools
7. Block Storage
7.1 Storage 介紹
Rock Ceph 提供了三種儲存型別,請參考官方指南瞭解詳情:
- Block Storage(RBD): Create block storage to be consumed by a pod (RWO)
- Filesystem Storage(CephFS): Create a filesystem to be shared across multiple pods (RWX)
- Object Storage(RGW): Create an object store that is accessible inside or outside the Kubernetes cluster
本文使用比較穩定、可靠的 Block Storage(RBD)的方式作為 Kubernetes 的持久化儲存。
7.2 建立儲存池
Rook 允許透過自定義資源定義 (crd) 建立和自定義 Block 儲存池。支援 Replicated 和 Erasure Coded 型別。本文演示 Replicated 的建立過程。
- 建立一個 3 副本的 Ceph 塊儲存池,編輯
CephBlockPool
CR 資源清單,vi ceph-replicapool.yaml
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: replicapool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
- 建立 CephBlockPool 資源
kubectl create -f ceph-replicapool.yaml
- 檢視資源建立情況
$ kubectl get cephBlockPool -n rook-ceph -o wide
NAME PHASE TYPE FAILUREDOMAIN REPLICATION EC-CODINGCHUNKS EC-DATACHUNKS AGE
replicapool Ready Replicated host 3 0 0 16s
- 在 ceph toolbox 中檢視 Ceph 叢集狀態
# 登入
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
# 檢視叢集
bash-5.1$ ceph -s
cluster:
id: e7913148-d29f-46fa-87a6-1c38ddb1530a
health: HEALTH_OK
services:
mon: 3 daemons, quorum a,b,c (age 10m)
mgr: a(active, since 8m), standbys: b
osd: 3 osds: 3 up (since 9m), 3 in (since 9m)
data:
pools: 2 pools, 2 pgs
objects: 3 objects, 577 KiB
usage: 81 MiB used, 300 GiB / 300 GiB avail
pgs: 2 active+clean
# 檢視叢集儲存池
bash-5.1$ ceph osd pool ls
.mgr
replicapool
bash-5.1$ rados df
POOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR USED COMPR UNDER COMPR
.mgr 1.7 MiB 2 0 6 0 0 0 106 91 KiB 137 1.8 MiB 0 B 0 B
replicapool 12 KiB 1 0 3 0 0 0 0 0 B 2 2 KiB 0 B 0 B
total_objects 3
total_used 81 MiB
total_avail 300 GiB
total_space 300 GiB
# 檢視儲存池的 pg number
bash-5.1$ ceph osd pool get replicapool pg_num
pg_num: 32
7.3 建立 StorageClass
- 編輯 StorageClass 資源清單,
vi storageclass-rook-ceph-block.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
# Change "rook-ceph" provisioner prefix to match the operator namespace if needed
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
# clusterID is the namespace where the rook cluster is running
clusterID: rook-ceph
# Ceph pool into which the RBD image shall be created
pool: replicapool
# RBD image format. Defaults to "2".
imageFormat: "2"
# RBD image features. Available for imageFormat: "2". CSI RBD currently supports only `layering` feature.
imageFeatures: layering
# The secrets contain Ceph admin credentials.
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
# Specify the filesystem type of the volume. If not specified, csi-provisioner
# will set default as `ext4`. Note that `xfs` is not recommended due to potential deadlock
# in hyperconverged settings where the volume is mounted on the same node as the osds.
csi.storage.k8s.io/fstype: ext4
# Delete the rbd volume when a PVC is deleted
reclaimPolicy: Delete
# Optional, if you want to add dynamic resize for PVC.
# For now only ext3, ext4, xfs resize support provided, like in Kubernetes itself.
allowVolumeExpansion: true
- 建立 StorageClass 資源
kubectl create -f storageclass-rook-ceph-block.yaml
注意: examples/csi/rbd 目錄中有更多的參考用例。
- 驗證資源
$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local openebs.io/local Delete WaitForFirstConsumer false 76d
nfs-sc (default) k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 22d
rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 11s
8. 建立測試應用
8.1 使用 Rook 提供的測試案例
我們使用 Rook 官方提供的經典的 Wordpress 和 MySQL 應用程式建立一個使用 Rook 提供塊儲存的示例應用程式,這兩個應用程式都使用由 Rook 提供的塊儲存卷。
- 建立 MySQL 和 Wordpress
kubectl create -f mysql.yaml
kubectl create -f wordpress.yaml
- 檢視 PVC 資源
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pv-claim Bound pvc-938fc531-cff8-452b-b89a-0040ac0aaa02 20Gi RWO rook-ceph-block 31s
wp-pv-claim Bound pvc-d94118de-7105-4a05-a4e7-ebc5807cc5c1 20Gi RWO rook-ceph-block 13s
- 檢視 SVC 資源
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 76d
wordpress LoadBalancer 10.233.25.187 <pending> 80:31280/TCP 33s
wordpress-mysql ClusterIP None <none> 3306/TCP 50s
- 檢視 Pod 資源
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
wordpress-6678b8879f-ql6sm 1/1 Running 0 49s 10.233.73.89 ksp-storage-2 <none> <none>
wordpress-mysql-5d69d6696b-fwttl 1/1 Running 0 67s 10.233.64.15 ksp-storage-1 <none> <none>
8.2 指定節點建立測試應用
Wordpress 和 MySQL 測試用例中,pod 建立在了儲存專用節點。為了測試叢集中其它 Worker 節點是否可以使用 Ceph 儲存,我們再做一個測試,在建立 Pod 時指定 nodeSelector
標籤,將 Pod 建立在非 rook-ceph 專用節點的 ksp-worker-1
上。
- 編寫測試 PVC 資源清單,
vi test-pvc-rbd.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc-rbd
spec:
storageClassName: rook-ceph-block
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
- 建立 PVC
kubectl apply -f test-pvc-rbd.yaml
- 檢視 PVC
$ kubectl get pvc -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
mysql-pv-claim Bound pvc-00c09bac-cee2-4a0e-9549-56f05b9c6965 20Gi RWO rook-ceph-block 77s Filesystem
test-pvc-rbd Bound pvc-ad475b29-6730-4c9a-8f8d-a0cd99b12781 2Gi RWO rook-ceph-block 5s Filesystem
wp-pv-claim Bound pvc-b3b2d6bc-6d62-4ac3-a50c-5dcf076d501c 20Gi RWO rook-ceph-block 76s Filesystem
- 編寫測試 Pod 資源清單,
vi test-pod-rbd.yaml
kind: Pod
apiVersion: v1
metadata:
name: test-pod-rbd
spec:
containers:
- name: test-pod-rbd
image: busybox:stable
command:
- "/bin/sh"
args:
- "-c"
- "touch /mnt/SUCCESS && sleep 3600"
volumeMounts:
- name: rbd-pvc
mountPath: "/mnt"
restartPolicy: "Never"
nodeSelector:
kubernetes.io/hostname: ksp-worker-1
volumes:
- name: rbd-pvc
persistentVolumeClaim:
claimName: test-pvc-rbd
- 建立 Pod
kubectl apply -f test-pod-rbd.yaml
- 檢視 Pod( Pod 按預期建立在了 ksp-worker-1 節點,並正確執行)
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-pod-rbd 1/1 Running 0 5s 10.233.94.210 ksp-worker-1 <none> <none>
wordpress-6678b8879f-ql6sm 1/1 Running 0 10m 10.233.73.89 ksp-storage-2 <none> <none>
wordpress-mysql-5d69d6696b-fwttl 1/1 Running 0 10m 10.233.64.15 ksp-storage-1 <none> <none>
- 檢視 Pod 掛載的儲存
$ kubectl exec test-pod-rbd -- df -h
Filesystem Size Used Available Use% Mounted on
overlay 99.9G 14.0G 85.9G 14% /
tmpfs 64.0M 0 64.0M 0% /dev
tmpfs 7.6G 0 7.6G 0% /sys/fs/cgroup
/dev/rbd0 1.9G 24.0K 1.9G 0% /mnt
/dev/mapper/openeuler-root
34.2G 2.3G 30.1G 7% /etc/hosts
/dev/mapper/openeuler-root
34.2G 2.3G 30.1G 7% /dev/termination-log
/dev/mapper/data-lvdata
99.9G 14.0G 85.9G 14% /etc/hostname
/dev/mapper/data-lvdata
99.9G 14.0G 85.9G 14% /etc/resolv.conf
shm 64.0M 0 64.0M 0% /dev/shm
tmpfs 13.9G 12.0K 13.9G 0% /var/run/secrets/kubernetes.io/serviceaccount
tmpfs 7.6G 0 7.6G 0% /proc/acpi
tmpfs 64.0M 0 64.0M 0% /proc/kcore
tmpfs 64.0M 0 64.0M 0% /proc/keys
tmpfs 64.0M 0 64.0M 0% /proc/timer_list
tmpfs 64.0M 0 64.0M 0% /proc/sched_debug
tmpfs 7.6G 0 7.6G 0% /proc/scsi
tmpfs 7.6G 0 7.6G 0% /sys/firmware
- 測試儲存空間讀寫
# 寫入 1GB 的資料
$ kubectl exec test-pod-rbd -- dd if=/dev/zero of=/mnt/test-disk.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1000.0MB) copied, 4.710019 seconds, 212.3MB/s
# 檢視結果
$ kubectl exec test-pod-rbd -- ls -lh /mnt/
total 1000M
-rw-r--r-- 1 root root 0 Aug 5 20:11 SUCCESS
drwx------ 2 root root 16.0K Aug 5 20:11 lost+found
-rw-r--r-- 1 root root 1000.0M Aug 5 20:14 test-disk.img
# 測試超限(再寫入 1GB 資料,只能寫入 929.8MB)
$ kubectl exec test-pod-rbd -- dd if=/dev/zero of=/mnt/test-disk2.img bs=1M count=1000
dd: error writing '/mnt/test-disk2.img': No space left on device
930+0 records in
929+0 records out
974987264 bytes (929.8MB) copied, 3.265758 seconds, 284.7MB/s
command terminated with exit code 1
# 再次檢視結果
$ kubectl exec test-pod-rbd -- ls -lh /mnt/
total 2G
-rw-r--r-- 1 root root 0 Aug 5 20:11 SUCCESS
drwx------ 2 root root 16.0K Aug 5 20:11 lost+found
-rw-r--r-- 1 root root 1000.0M Aug 5 20:14 test-disk.img
-rw-r--r-- 1 root root 929.8M Aug 5 20:18 test-disk2.img
注意: 測試時,我們寫入了 2G 的資料量,當達過我們建立的 PVC 2G 容量上限時會報錯(實際使用寫不滿 2G)。說明,Ceph 儲存可以做到容量配額限制。
9. Ceph Dashboard
Ceph 提供了一個 Dashboard 工具,我們可以在上面檢視叢集的狀態,包括叢集整體執行狀態、Mgr、Mon、OSD 和其他 Ceph 程序的狀態,檢視儲存池和 PG 狀態,以及顯示守護程序的日誌等。
部署叢集的配置檔案 cluster.yaml
,預設已經開啟了 Dashboard 功能,Rook Ceph operator 部署叢集時將啟用 ceph-mgr 的 Dashboard 模組。
9.1 獲取 Dashboard 的 service 地址
$ kubectl -n rook-ceph get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rook-ceph-exporter ClusterIP 10.233.4.126 <none> 9926/TCP 46m
rook-ceph-mgr ClusterIP 10.233.49.41 <none> 9283/TCP 46m
rook-ceph-mgr-dashboard ClusterIP 10.233.7.182 <none> 8443/TCP 46m
rook-ceph-mon-a ClusterIP 10.233.45.222 <none> 6789/TCP,3300/TCP 47m
rook-ceph-mon-b ClusterIP 10.233.52.144 <none> 6789/TCP,3300/TCP 47m
rook-ceph-mon-c ClusterIP 10.233.57.144 <none> 6789/TCP,3300/TCP 47m
9.2 配置在叢集外部訪問 Dashboard
通常我們需要在 K8s 叢集外部訪問 Ceph Dashboard,可以透過 NodePort 或是 Ingress 的方式。
本文演示 NodePort 方式。
- 建立資源清單檔案,
vi ceph-dashboard-external-https.yaml
apiVersion: v1
kind: Service
metadata:
name: rook-ceph-mgr-dashboard-external-https
namespace: rook-ceph
labels:
app: rook-ceph-mgr
rook_cluster: rook-ceph
spec:
ports:
- name: dashboard
port: 8443
protocol: TCP
targetPort: 8443
nodePort: 31443
selector:
app: rook-ceph-mgr
mgr_role: active
rook_cluster: rook-ceph
type: NodePort
- 建立資源
kubectl create -f ceph-dashboard-external-https.yaml
- 驗證建立的資源
$ kubectl -n rook-ceph get service rook-ceph-mgr-dashboard-external-https
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rook-ceph-mgr-dashboard-external-https NodePort 10.233.5.136 <none> 8443:31443/TCP 5s
9.3 獲取 Login Credentials
登陸 Dashboard 時需要身份驗證,Rook 建立了一個預設使用者,使用者名稱 admin。建立了一個名為 rook-ceph-dashboard-password
的 secret 儲存密碼,使用下面的命令獲取隨機生成的密碼。
$ kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo
6W6#Y3PvI~=CVq0f'@Yo
9.4 透過瀏覽器開啟 Dashboard
訪問 K8s 叢集中任意節點的 IP,https://192.168.9.91:31443
,預設使用者名稱 admin
,密碼透過上面的命令獲取。
9.5 Ceph Dashboard 概覽
Ceph Dashboard 雖然介面簡單,但是常用的管理功能都具備,能實現圖形化管理儲存資源。下面展示幾張截圖,作為本文的結尾。
- Dashboard
- 叢集-主機
- 叢集-OSD
- 儲存池
免責宣告:
- 筆者水平有限,儘管經過多次驗證和檢查,盡力確保內容的準確性,但仍可能存在疏漏之處。敬請業界專家大佬不吝指教。
- 本文所述內容僅透過實戰環境驗證測試,讀者可學習、借鑑,但嚴禁直接用於生產環境。由此引發的任何問題,作者概不負責!
本文由部落格一文多發平臺 OpenWrite 釋出!