使用 Rook 構建生產可用存儲環境實踐

Rook 是基於 Kubernetes 之上構建的存儲服務框架。它支持 Ceph、NFS 等多種底層存儲的創建和管理。幫助系統管理員自動化維護存儲的整個生命週期。存儲的整個生命週期包括部署、啓動、配置、申請、擴展、升級、遷移、災難恢復、監控和資源管理等,看着就讓筆者覺得事情不少,Rook 的目標就是降低運維的難度,讓 Kubernetes 和 Rook 來幫你託管解決這些任務。

Rook 管理 Ceph 集羣

Ceph 分佈式存儲是 Rook 支持的第一個標記爲 Stable 的編排存儲引擎,在筆者驗證 Rook 操作 Ceph 的過程中發現,其社區文檔、腳本都放在一起,初次新手很難知道如何一步一步體驗 Rook 搭建 Ceph 的過程。這從一個側面反應了分佈式存儲的技術難度和兼容性是一個長期的迭代過程,Rook 的本意是爲了降低部署管理 Ceph 集羣的難度,但是事與願違,初期使用的過程並不友好,有很多不知名的問題存在官方文檔中。

在安裝 Ceph 前要注意,目前最新的 Ceph 支持的存儲後端 BlueStore 僅支持裸設備,不支持在本地文件系統之上建立存儲塊。因爲 Rook 文檔的混亂,一開始我們需要自己找到安裝腳本目錄,它在https://github.com/rook/rook/tree/master/cluster/examples/kubernetes/ceph

$ git clone https://github.com/rook/rook.git
cd rook
$ git checkout release-1.4
cd cluster/examples/kubernetes/ceph
$ kubectl create -f common.yaml
# 檢查 namesapce 是否有 rook-ceph 了
$ kubectl get namespace
$ kubectl create -f operator.yaml
# 上述的步驟必須確定 pods 已經處於 running or complete 才能做下一個階段,否則很有可能會 fail,上述的步驟需要等一會。
$ kubectl create -f cluster.yaml
# 等待 Ceph 集羣創建成功。
$ kubectl -n rook-ceph get pods
# mgr 1, mon 3, 
# rook-ceph-crashcollector (有幾個 node 就有幾個)
# rook-ceph-osd (有幾個 disk,就會有幾個 pod,排序從 0 開始)

Ceph 的問題很多,經常需要使用工具箱查看一些情況,按照如下步驟部署:


$ kubectl create -f toolbox.yaml
$ kubectl -n rook-ceph get pods | grep ceph-tools
rook-ceph-tools-649c4dd574-gw8tx   1/1  Running  0   3m20s
$ kubectl -n rook-ceph exec -it rook-ceph-tools-649c4dd574-gw8tx bash
$ ceph -s
cluster:
    id:     9ca03dd5-05bc-467f-89a8-d3dfce3b9430
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum a,d,e (age 12m)
    mgr: a(active, since 8m)
    osd: 44 osds: 44 up (since 13m), 44 in (since 13m)

  data:
    pools:   1 pools, 1 pgs
    objects: 0 objects, 0 B
    usage:   45 GiB used, 19 TiB / 19 TiB avail
    pgs:     1 active+clean

# ceph 集羣可以使用的容量
$ ceph df
# ceph osd 與 node 的關係分佈
$ ceph osd tree
# 刪除 ceph toolbox 工具
$ kubectl delete -f toolbox.yaml

使用 Dashboard 查看 Ceph 運行情況:


$ vim 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
  selector:
    app: rook-ceph-mgr
    rook_cluster: rook-ceph
  sessionAffinity: None
  type: NodePort
$ kubectl create -f dashboard-external-https.yaml
$ kubectl -n rook-ceph get service
rook-ceph-mgr-dashboard-external-https   NodePort    10.107.117.151   <none>        8443:31955/TCP      8m23s

訪問地址是 31955,https://master_ip:31955 就可以訪問。賬號是 admin,密碼可以在線查到:

$ kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo

清空 Ceph:

cd /rook/cluster/examples/kubernetes/ceph
$ kubectl -n rook-ceph delete cephcluster rook-ceph
$ kubectl -n rook-ceph get cephcluster
# 確認 rook-ceph 被刪除
$ kubectl delete -f operator.yaml
# 刪除集羣
$ kubectl delete -f common.yaml
$ kubectl delete -f cluster.yaml

用 Rook 管理 NFS 文件系統

NFS 文件系統目前在國內企業還是很常見的一種存儲方案。用 Rook 來管理 NFS 文件系統可以極大的方便開發者的存儲環境。安裝 rook 之前需要先安裝 NFS Client 安裝包。在 CentOS 節點上安裝 nf-utils,在 Ubuntu 節點上安裝 nf-common。然後就可以安裝 Rook 了。步驟如下:

git clone --single-branch --branch v1.4.6 https://github.com/rook/rook.git
cd rook/cluster/examples/kubernetes/nfs
kubectl create -f common.yaml
kubectl create -f provisioner.yaml
kubectl create -f operator.yaml



#查看運行情況
[root@dev-mng-temp ~]# kubectl -n rook-nfs-system get pod
NAME                                   READY   STATUS    RESTARTS   AGE
rook-nfs-operator-59fb455d77-2cxn4     1/1     Running   0          75m
rook-nfs-provisioner-b4bbf4cc4-qrzqd   1/1     Running   1          75m

創建權限,rbac.yaml 內容如下:

---
apiVersion: v1
kind: Namespace
metadata:
  name:  rook-nfs
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rook-nfs-server
  namespace: rook-nfs
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rook-nfs-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get""list""watch""create""delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get""list""watch""update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get""list""watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create""update""patch"]
  - apiGroups: [""]
    resources: ["services""endpoints"]
    verbs: ["get"]
  - apiGroups: ["policy"]
    resources: ["podsecuritypolicies"]
    resourceNames: ["rook-nfs-policy"]
    verbs: ["use"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get""list""watch""create""update""patch"]
  - apiGroups:
    - nfs.rook.io
    resources:
    - "*"
    verbs:
    - "*"
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rook-nfs-provisioner-runner
subjects:
  - kind: ServiceAccount
    name: rook-nfs-server
     # replace with namespace where provisioner is deployed
    namespace: rook-nfs
roleRef:
  kind: ClusterRole
  name: rook-nfs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

執行 yaml 創建權限:

kubectl create -f rbac.yaml

當前主流的做法是採用動態申請資源的方式創建 NFSServer,步驟如下:

kubectl create -f nfs.yaml

# sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  labels:
    app: rook-nfs
  name: rook-nfs-share1
parameters:
  exportName: share1
  nfsServerName: rook-nfs
  nfsServerNamespace: rook-nfs
provisioner: rook.io/nfs-provisioner
reclaimPolicy: Delete
volumeBindingMode: Immediate

kubectl create -f sc.yaml 將創建 StorageClass,然後就可以申請資源:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rook-nfs-pv-claim
spec:
  storageClassName: "rook-nfs-share1"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

kubectl create -f pvc.yaml 將創建一份文件卷。校驗結果:


[root@dev-mng-temp nfs]# kubectl get pvc
NAME                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
rook-nfs-pv-claim   Bound    pvc-504eb26d-1b6f-4ad8-9318-75e637ab50c7   1Mi        RWX            rook-nfs-share1   7m5s

測試使用的案例:

> kubectl create -f busybox-rc.yaml
> kubectl create -f web-rc.yaml

> kubectl get pod -l app=nfs-demo

> kubectl create -f web-service.yaml

echo; kubectl exec $(kubectl get pod -l app=nfs-demo,role=busybox -o jsonpath='{.items[0].metadata.name}') -- wget -qO- http://$(kubectl get services nfs-web -o jsonpath='{.spec.clusterIP}'); echo

Thu Oct 22 19:28:55 UTC 2015
nfs-busybox-w3s4t

當你發現 NFS Server 沒有運行起來,可以用這一行命令查看問題:

kubectl -n rook-nfs-system logs -l app=rook-nfs-operator

總結

Rook 項目從筆者入手來,其目標定位還是很準,並且真實的解決了簡化 Ceph 安裝配置的痛點,並且依據 Ceph 使用的經驗開始注入更多的存儲驅動,如 NFS 存儲驅動。使用起來並不複雜,但是它的文檔實在是太糟糕了。社區中也沒有人來專門維護這套文檔,導致文章中很多描述都是過期的,你根本不清楚如何配置。一不小心就會配置錯誤。所以大家在使用過程中,還是要仔細熟悉一遍 yaml 文檔的內容,瞭解到它的功能後在安裝,就會事半功倍。這種不完善其實對開源技術愛好者來說,也是一種機會,讓你通過修改文檔的方式參與到 Rook 這個項目中。以我梳理一遍之後,通過最新版本的安裝步驟,你可以幾分鐘就可以部署自己的分佈式存儲環境,Rook 確實事半功倍,值得推薦並大量實踐使用。

參考資料

https://draveness.me/papers-ceph/ 

https://rook.io/docs/rook/v1.4/nfs.html

本文分享自微信公衆號 - 雲原生技術愛好者社區(programmer_java)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章