探索 Kubernetes 持久化儲存之 Rook Ceph 初窺門徑

kubesphere發表於2024-08-13

在 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 釋出!

相關文章