如何通過 Rook-Ceph 升級 NFS 服務

高瑞冬,中國移動磐基 PaaS 平臺中間件專業服務項目資深顧問,專注於雲原生等領域產品研發。

1.前言

nfs 是廣泛使用的網絡化存儲服務,用戶基礎大,技術成熟,具有操作知識的工程師很多。但是,在雲原生和分佈式存儲的角度看,原生的 nfs 存儲服務不能提供存儲高可用能力,然而存儲高可用能力是雲原生的普遍需求。

本文探索通過 ceph 爲 nfs 服務提供存儲的高可用的可行方案。ceph 存儲結合 nfs-ganesha 服務,爲 nfs 客戶端提供了基於 ceph 對象存儲的 nfs 協議輸出。ceph 提供的存儲類型豐富,包括 RBD,cephfs,RGW,能夠有效滿足不同業務場景的需求。本文給出了提供 cephfs 和 RGW 兩種後端存儲機制的 nfs 集成方案。期望 nfs 的衆多用戶可以在雲原生環境中繼續安心使用熟悉的 nfs 掛載提供存儲能力,而同時獲得了 ceph 存儲提供的多副本或者糾刪碼的高可用特性,滿足雲原生環境對業務運行的新需求。

本文嘗試通過 rook(1.10.11) 管理的 ceph(17.2.5) 創建 nfs 導出,爲 nfs 用戶提供一種新的選擇和參考。

2.準備 cephfs 後端存儲

2.1  cephfs 的一些準備性知識

Volume 是 cephfs 文件系統的一個抽象。在這個層面可以指定存儲使用的 ceph 池,從而指定是使用多副本還是糾錯碼作爲數據高可用的提供者。每個 volume 會有獨立的 metadata server 爲其提供目錄等元數據服務。

subvolume 是對 cephfs 文件系統目錄的抽象。cephfs 對外存儲是以 subvolume 爲單位供給。K8s 中爲容器申請一塊 cephfs 存儲空間就是一個 subvolume。

subvolumegroup 是比 subvolume 更高層面的目錄抽象。這個層面可以控制策略(如文件佈局等)。這裏設置的策略會在其下的 subvolume 中應用。

2.2  創建 cephfs volume

首先我們通過 rook 提供的如下 yaml 創建一個三副本的 cephfs(ceph 文件系統):

apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
  name: cephfs4nfs
  namespace: rook-ceph
spec:
  metadataPool:
    replicated:
      size: 3
      requireSafeReplicaSize: true
    parameters:
      compression_mode:
        none
  dataPools:
    - name: replicated
      failureDomain: host
      replicated:
        size: 3
        requireSafeReplicaSize: true
      parameters:
        compression_mode:
          none
  preserveFilesystemOnDelete: true
  metadataServer:
    activeCount: 1
    activeStandby: true
    placement:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
                - key: app
                  operator: In
                  values:
                    - rook-ceph-mds
            topologyKey: kubernetes.io/hostname
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - rook-ceph-mds
              topologyKey: topology.kubernetes.io/zone
    priorityClassName: system-cluster-critical
    livenessProbe:
      disabled: false
    startupProbe:
      disabled: false

使用 rook 提供的 krew 插件 rook-ceph 命令,可以 ceph 命令行的形式直接操作 k8s 中的 ceph 集羣,如同 ceph 的主機化部署一樣。如下命令用來查看上面新文件系統對應的 ceph 存儲池是否已經創建:

kubectl rook-ceph ceph osd pool ls | grep cephfs4nfs
cephfs4nfs-metadata
cephfs4nfs-replicated

可以看到爲新文件系統已經創建兩個存儲池:

2.3  創建 cephfs 上的 nfs 導出目錄

目前需要使用 ceph 原生命令查看創建出來的 ceph 文件系統。工程上一般不會把整個 cephfs volume 做 nfs 導出,那麼在新創建的 cephfs volume 上創建一個 subvolumegroup 常常是很有必要的,subvolumegroup 對應的是 ceph 文件系統的目錄。以此便於控制 nfs 導出訪問權限,容量,專門用於 nfs 掛載。以下命令創建了空間配額爲 204800KB 的 subvolumegroup:

kubectl rook-ceph ceph fs subvolumegroup create cephfs4nfs nfsexport --size 204800

需要查看並記錄創建的這個 subvolumegroup 的絕對路徑,這個路徑在創建 nfs export 時候需要用到:

kubectl rook-ceph ceph fs subvolumegroup getpath cephfs4nfs nfsexport             
/volumes/nfsexport

3.準備 RGW 後端存儲

爲了提供 nfs 導出的 RGW 後端存儲,我們需要在 ceph 中創建一個存儲對象桶(bucket),通過 nfs 讀寫的業務數據將存儲在這個桶的對象中。

創建對象桶可以通過 s3 客戶端完成,這裏我們使用 ceph 的儀表盤可視化的完成這個操作。通過瀏覽器打開儀表盤,在左側菜單欄中選擇 Object Gateway/Buckets,打開對象桶的管理頁面。

頁面上點擊 Create。在頁面中填入對象名稱 bkt4exp,選擇一個 owner,選擇合適的放置點,點擊 Create bucket 完成創建。

這個對象桶將在後面創建 nfs rgw 導出時使用。

4.創建 ganesha-nfs 服務提供 nfs 導出

然後我們通過 rook 提供的 cephnfs 模版創建一個 nfs 集羣。這一步將在 k8s 上啓動一個基於 ganesha-nfs 的服務。

apiVersion: ceph.rook.io/v1
kind: CephNFS
metadata:
  name: nfs-cluster
  namespace: rook-ceph
spec:
  server:
    active: 1
    logLevel: NIV_INFO

稍後會有 pod 啓動,正是 pod 中運行的這個服務提供 nfs 導出到 ceph 存儲的轉換服務。

運行 kubectl rook-ceph ceph nfs cluster ls

nfs-cluster
nfs4cephfs
nfs4rgw

可以看到新的 nfs 集羣 nfs-cluster 已經創建出來了。

爲了掛載 nfs 導出,需要查看和記錄 nfs-ganesha 服務 nfs-cluster 所在的 ip。下面輸出的結果顯示 nfs 服務 ip 地址是 169.169.165.85。

kubectl get svc -n rook-ceph| grep nfs-cluster
rook-ceph-nfs-nfs-cluster-a              ClusterIP   169.169.165.85    <none>
2049/TCP            9m29s

5.創建 nfs 導出

nfs-ganesha 服務已經就緒,需要的信息也已經蒐集和記錄。這樣我們就可以根據需要創建 nfs 導出了。目前 ceph 支持使用 cephfs 和 rgw 作爲存儲後端。

5.1  創建 cephfs 導出

下面是在 ceph 系統內部創建一個基於 cephfs 的 nfs 導出,掛載到 cephfs4nfs 文件系統的目錄 / volumes/nfsexport 下。這個目錄是在前面 2.3 節中準備好的。運行如下命令:

 kubectl rook-ceph ceph nfs export create cephfs nfs-cluster /fsexport cephfs4nfs /volumes/nfsexport 
{
    "bind": "/fsexport",
    "fs": "cephfs4nfs",
    "path": "/volumes/nfsexport",
    "cluster": "nfs-cluster",
    "mode": "RW"
}

nfs 導出創建成功。在可以訪問此服務的主機環境下,運行如下命令掛載 nfs 存儲:

mount -t nfs -o port=2049,nfsvers=4.1,noauto,soft,sync,proto=tcp 169.169.165.85:/fsexport /mnt/mountpoint/cephfs

這樣掛載成功以後,就可以通過目錄 / mnt/mountpoint/cephfs 使用這個數據高可用的存儲了。

5.2  創建 rgw 導出

使用對象存儲提供 nfs 的底層支持有一定的優勢。首先是對象存儲具有比 cephfs 更加簡潔的技術堆棧,數據的讀寫效率比較高。其次對象存儲同樣的具有 ceph 的數據高可用特性。這無疑爲 nfs 的老鐵用戶帶來了無縫升級 nfs 卻又接口無憂的一個技術方案。

不過這部分功能目前還處於初期。其中存在一個 bug 導致 rgw 導出創建以後,ganesha-nfs 服務循環重啓。這個問題得到社區的反饋和關注,已經有一個 PR 正在提交解決中:

lhttps://github.com/rook/rook/pull/11598

在這個修復合併到 master 前,我們可以通過如下步驟繞過這個問題:

創建配置文件 rgw.conf,內容如下:


RGW
{
        name = "client.nfs-ganesha.nfs-cluster.a";
}

運行如下命令,設置 nfs-cluster 服務的用戶定義配置:

ceph nfs cluster config set nfs-cluster -i ./rgw.conf

設置完成以後需要重啓 nfs-ganesha 服務。

爬過了這個坑,我們就可以開始創建 rgw nfs 導出了。

使用第 3 節中準備的 RGW 存儲桶,可以藉助 nfs-ganesha 服務在存儲桶 bkt4exp 上完成 nfs export 的創建。運行如下命令:

ceph nfs export create rgw --cluster-id nfs-cluster --pseudo-path /rgwexport --bucket bkt4exp

在可以訪問此服務的主機環境下,使用和 cephfs 導出相同的 nfs-ganesha 服務完成掛載:

mount -t nfs -o port=2049,nfsvers=4.1,noauto,soft,sync,proto=tcp 169.169.165.85:/rgwexport  /mnt/mountpoint/rgw

這樣掛載成功以後,就可以通過目錄 / mnt/mountpoint/rgw 使用這個數據高可用的存儲了。

6.總結

目前存在的其他的類似方案一般是非雲原生環境的主機化部署,往往需要繁複的 ceph 命令行操作,對技術棧中各個組件需要單獨的修改配置文件。通過 rook 管理 ceph 集羣,同樣的 ceph nfs 導出配置過程得到很大的簡化。一方面體現了聲明式編程的強大力量。另一方面也能夠看到 operator sdk 爲複雜系統的運維知識的封裝提供了完美的支撐。

至此我們走了一遍基於 cephfs 和 rgw 的 nfs 導出和掛載過程。rook 這方面的相關資料比較少,本文給出了完整的實施步驟,相信對雲原生環境下小夥伴們深入使用 nfs 存儲能夠有所幫助。雖然目前 RGW 導出功能還處於試驗階段。不過通過 cephfs 的導出的 nfs 還是很值得在實際環境中考慮使用的。

另外的一個場景是 nfs 導出服務(nfs-ganesha)的高可用。目前社區還在討論和開發中,相信通過開源社區的協同努力,這方面的需求在不久的將來也能夠得到很好的滿足。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/lhUBPLmJRkIHGya4kd0Qcw