快速上手 Rook,入門雲原生儲存編排

為少發表於2021-08-04

Rook 是一個開源 cloud-native storage orchestrator(雲原生儲存編排器),為各種儲存解決方案提供平臺、框架和支援,以與雲原生環境進行原生整合。

Rook 將儲存軟體轉變為自我管理(self-managing)、自我擴充套件(self-scaling)和自我修復(self-healing)的儲存服務。
它通過自動化部署(automating deployment)、引導(bootstrapping)、配置(configuration)、供應(provisioning)、
擴充套件(scaling)、升級(upgrading)、遷移(migration)、災難恢復(disaster recovery)、監控(monitoring)和資源管理(resource management)來實現這一點。
Rook 使用底層雲原生容器管理、排程和編排平臺提供的設施來執行其職責。

Rook 利用擴充套件點深度整合到雲原生環境中,併為排程、生命週期管理、資源管理、安全、監控和使用者體驗提供無縫體驗。

Cassandra 快速入門

Cassandra 是一個高可用、容錯、對等的 NoSQL 資料庫,具有閃電般的效能和可調的一致性。它提供了無單點故障的大規模可擴充套件性。

Scylla 是在 C++ 中對 Cassandra 的接近硬體重寫。
它採用無共享架構,可實現真正的線性擴充套件和主要硬體優化,從而實現超低延遲和極高吞吐量。它是 Cassandra 的直接替代品,並使用相同的介面,因此 Rook 也支援它。

前提條件

執行 Rook Cassandra operator 需要 Kubernetes 叢集。
為了確保你有一個為 Rook 準備好的 Kubernetes 叢集(Cassandra 不需要 flexvolume 外掛)

部署 Cassandra Operator

首先使用以下命令部署 Rook Cassandra Operator

$ git clone --single-branch --branch v1.6.8 https://github.com/rook/rook.git
cd rook/cluster/examples/kubernetes/cassandra
kubectl apply -f operator.yaml

這將在名稱空間 rook-cassandra-system 中安裝 operator。您可以檢查 operator 是否已啟動並執行:

kubectl -n rook-cassandra-system get pod

建立和初始化 Cassandra/Scylla 叢集

現在 operator 正在執行,我們可以通過建立 clusters.cassandra.rook.io 資源的例項來建立 Cassandra/Scylla 叢集的例項。
該資源的某些值是可配置的,因此請隨意瀏覽 cluster.yaml 並根據自己的喜好調整設定。

當你準備建立一個 Cassandra 叢集時,只需執行:

kubectl create -f cluster.yaml

我們可以使用以下命令驗證是否已建立代表我們新 Cassandra 叢集的 Kubernetes 物件。
這很重要,因為它表明 Rook 已成功擴充套件 Kubernetes,使 Cassandra 叢集成為 Kubernetes 雲原生環境中的一等公民。

kubectl -n rook-cassandra get clusters.cassandra.rook.io

要檢查是否所有所需的成員都在執行,您應該從以下命令中看到與 cluster.yaml 中指定的成員數量相同的條目數:

kubectl -n rook-cassandra get pod -l app=rook-cassandra

您還可以從其狀態跟蹤 Cassandra 叢集的狀態。要檢查叢集的當前狀態,請執行:

kubectl -n rook-cassandra describe clusters.cassandra.rook.io rook-cassandra

訪問資料庫

  • 從 kubectl:

要在新叢集中獲取 cqlsh shell:

kubectl exec -n rook-cassandra -it rook-cassandra-east-1-east-1a-0 -- cqlsh
> DESCRIBE KEYSPACES;
  • 從 Pod 內部:

當你建立一個新的叢集時,Rook 會自動為客戶端建立一個服務來訪問叢集。服務的名稱遵循約定<cluster-name>-client。您可以通過執行以下命令在叢集中檢視此服務:

kubectl -n rook-cassandra describe service rook-cassandra-client

在 Kubernetes 叢集中執行的 Pod 可以使用此服務連線到 Cassandra
這是使用 Python Driver 的示例:

from cassandra.cluster import Cluster

cluster = Cluster(['rook-cassandra-client.rook-cassandra.svc.cluster.local'])
session = cluster.connect()

Scale Up

operator 支援擴充套件機架(rack)以及新增新機架(rack)。要進行更改,您可以使用:

kubectl edit clusters.cassandra.rook.io rook-cassandra
  • 要擴充套件一個 rack,請將 rackSpec.Members 欄位更改為所需值。
  • 要新增新 rack,請在 racks 列表中新增一個新 rack。請記住為新 rack 選擇不同的 rack 名稱。
  • 編輯並儲存 yaml 後,請檢查叢集的狀態和事件以獲取有關正發生情況的資訊:
kubectl -n rook-cassandra describe clusters.cassandra.rook.io rook-cassandra

Scale Down

operator 支援按比例縮小 rack。要進行更改,您可以使用:

kubectl edit clusters.cassandra.rook.io rook-cassandra
  • 要縮小一個 rack,請將 rackSpec.Members 欄位更改為所需值。
  • 編輯並儲存 yaml 後,請檢查叢集的狀態和事件以獲取有關正發生情況的資訊:
kubectl -n rook-cassandra describe clusters.cassandra.rook.io rook-cassandra

Clean Up

要清理與此演練相關的所有資源,您可以執行以下命令。

注意:這將破壞您的資料庫並刪除其所有相關資料。

kubectl delete -f cluster.yaml
kubectl delete -f operator.yaml

故障排除

如果叢集沒有出現,第一步是檢查 operator 的日誌:

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

如果 operator 日誌中一切正常,您還可以檢視 Cassandra 例項之一的日誌:

kubectl -n rook-cassandra logs rook-cassandra-0

Cassandra 監控

要為 cassandra rack 啟用 jmx_exporter,您應該在 CassandraCluster CRD 中為 rack 指定 jmxExporterConfigMapName 選項。

例如:

apiVersion: cassandra.rook.io/v1alpha1
kind: Cluster
metadata:
  name: my-cassandra
  namespace: rook-cassandra
spec:
  ...
  datacenter:
    name: my-datacenter
    racks:
    - name: my-rack
      members: 3
      jmxExporterConfigMapName: jmx-exporter-settings
      storage:
        volumeClaimTemplates:
        - metadata:
            name: rook-cassandra-data
          spec:
            storageClassName: my-storage-class
            resources:
              requests:
                storage: 200Gi

獲取所有指標的簡單 config map 示例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: jmx-exporter-settings
  namespace: rook-cassandra
data:
  jmx_exporter_config.yaml: |
    lowercaseOutputLabelNames: true
    lowercaseOutputName: true
    whitelistObjectNames: ["org.apache.cassandra.metrics:*"]

ConfigMap 的資料欄位必須包含帶有 jmx exporter 設定的 jmx_exporter_config.yaml key。

config map 更新時,Pod 沒有自動重新載入機制。
configmap 更改後,您應該手動重新啟動所有 rack pods:

NAMESPACE=<namespace>
CLUSTER=<cluster_name>
RACKS=$(kubectl get sts -n ${NAMESPACE} -l "cassandra.rook.io/cluster=${CLUSTER}")
echo ${RACKS} | xargs -n1 kubectl rollout restart -n ${NAMESPACE}

Ceph Storage 快速入門

本指南將引導您完成 Ceph 叢集的基本設定,並使您能夠使用叢集中執行的其他 pod 中的塊、物件和檔案儲存。

最低版本

Rook 支援 Kubernetes v1.11 或更高版本。

Important 如果您使用的是 K8s 1.15 或更早版本,則需要建立不同版本的 Rook CRD。
建立在示例清單的 pre-k8s-1.16 子資料夾中找到的 crds.yaml

前提條件

為確保您擁有可用於 RookKubernetes 叢集。

為了配置 Ceph 儲存叢集,至少需要以下本地儲存選項之一:

  • 原始裝置(無分割槽或格式化檔案系統)
    • 這需要在主機上安裝 lvm2
      為了避免這種依賴性,您可以在磁碟上建立一個完整的磁碟分割槽(見下文)
  • 原始分割槽(無格式化檔案系統)
  • block 模式下儲存類中可用的持久卷

您可以使用以下命令確認您的分割槽或裝置是否已格式化檔案系統。

lsblk -f
NAME                  FSTYPE      LABEL UUID                                   MOUNTPOINT
vda
└─vda1                LVM2_member       >eSO50t-GkUV-YKTH-WsGq-hNJY-eKNf-3i07IB
 ├─ubuntu--vg-root   ext4              c2366f76-6e21-4f10-a8f3-6776212e2fe4   /
 └─ubuntu--vg-swap_1 swap              9492a3dc-ad75-47cd-9596-678e8cf17ff9   [SWAP]
vdb

如果 FSTYPE 欄位不為空,則在相應裝置的頂部有一個檔案系統。在這種情況下,您可以將 vdb 用於 Ceph,而不能使用 vda 及其分割槽。

TL;DR

如果幸運的話,可以使用以下 kubectl 命令和示例 yaml 檔案建立一個簡單的 Rook 叢集。

$ git clone --single-branch --branch v1.6.8 https://github.com/rook/rook.git
cd rook/cluster/examples/kubernetes/ceph
kubectl create -f crds.yaml -f common.yaml -f operator.yaml
kubectl create -f cluster.yaml

叢集環境

Rook 文件側重於在生產環境中啟動 Rook。還提供了一些示例來放寬測試環境的一些設定。在本指南後面建立叢集時,請考慮以下示例叢集清單:

  • cluster.yaml: 在裸機上執行的生產叢集的叢集設定。至少需要三個工作節點。
  • cluster-on-pvc.yaml: 在動態雲環境中執行的生產叢集的叢集設定。
  • cluster-test.yaml: 測試環境的叢集設定,例如 minikube。

部署 Rook Operator

第一步是部署 Rook operator。檢查您是否正在使用與您的 Rook 版本相對應的示例 yaml 檔案

cd cluster/examples/kubernetes/ceph
kubectl create -f crds.yaml -f common.yaml -f operator.yaml

# verify the rook-ceph-operator is in the `Running` state before proceeding
kubectl -n rook-ceph get pod

在生產中啟動 Operator 之前,您可能需要考慮一些設定:

  1. 如果您使用 kubernetes v1.15 或更早版本,則需要在此處建立 CRD,在 /cluster/examples/kubernetes/ceph/pre-k8s-1.16/crd.yaml
    CustomResourceDefinitionapiextension v1beta1 版本在 Kubernetes v1.16 中已棄用。
  2. 考慮是否要啟用預設禁用的某些 Rook 功能。有關這些和其他高階設定,請參閱 operator.yaml
    1. 裝置發現:如果啟用了 ROOK_ENABLE_DISCOVERY_DAEMON 設定,Rook 將監視要配置的新裝置,常用於裸機叢集。
    2. Flex driver:Flex driver 已被棄用,取而代之的是 CSI driver,但仍可通過 ROOK_ENABLE_FLEX_DRIVER 設定啟用。
    3. Node affinity and tolerations(節點關聯和容忍度):預設情況下,CSI driver 將在叢集中的任何節點上執行。 要配置 CSI driver affinity,可以使用多種設定。

建立 Rook Ceph 叢集

現在 Rook operator 正在執行,我們可以建立 Ceph 叢集。
為了使叢集在重新啟動後繼續存在,請確保設定對主機有效的 dataDirHostPath 屬性。

建立叢集:

kubectl create -f cluster.yaml

使用 kubectl 列出 rook-ceph 名稱空間中的 pod。
一旦它們全部執行,您應該能夠看到以下 pod
osd pod 的數量將取決於叢集中的節點數量和配置的裝置數量。
如果沒有修改上面的 cluster.yaml,預計每個節點會建立一個 OSD
CSI、rook-ceph-agent(flex driver)和 rook-discover pod 也是可選的,具體取決於您的設定。

kubectl -n rook-ceph get pod
NAME                                                 READY   STATUS      RESTARTS   AGE
csi-cephfsplugin-provisioner-d77bb49c6-n5tgs         5/5     Running     0          140s
csi-cephfsplugin-provisioner-d77bb49c6-v9rvn         5/5     Running     0          140s
csi-cephfsplugin-rthrp                               3/3     Running     0          140s
csi-rbdplugin-hbsm7                                  3/3     Running     0          140s
csi-rbdplugin-provisioner-5b5cd64fd-nvk6c            6/6     Running     0          140s
csi-rbdplugin-provisioner-5b5cd64fd-q7bxl            6/6     Running     0          140s
rook-ceph-crashcollector-minikube-5b57b7c5d4-hfldl   1/1     Running     0          105s
rook-ceph-mgr-a-64cd7cdf54-j8b5p                     1/1     Running     0          77s
rook-ceph-mon-a-694bb7987d-fp9w7                     1/1     Running     0          105s
rook-ceph-mon-b-856fdd5cb9-5h2qk                     1/1     Running     0          94s
rook-ceph-mon-c-57545897fc-j576h                     1/1     Running     0          85s
rook-ceph-operator-85f5b946bd-s8grz                  1/1     Running     0          92m
rook-ceph-osd-0-6bb747b6c5-lnvb6                     1/1     Running     0          23s
rook-ceph-osd-1-7f67f9646d-44p7v                     1/1     Running     0          24s
rook-ceph-osd-2-6cd4b776ff-v4d68                     1/1     Running     0          25s
rook-ceph-osd-prepare-node1-vx2rz                    0/2     Completed   0          60s
rook-ceph-osd-prepare-node2-ab3fd                    0/2     Completed   0          60s
rook-ceph-osd-prepare-node3-w4xyz                    0/2     Completed   0          60s

要驗證叢集是否處於健康狀態,請連線到 Rook toolbox 並執行 ceph status 命令。

  • 所有 mons 都應達到法定人數
  • mgr 應該是活躍的
  • 至少有一個 OSD 處於活動狀態
  • 如果執行狀況不是 HEALTH_OK,則應調查警告或錯誤
ceph status
 cluster:
   id:     a0452c76-30d9-4c1a-a948-5d8405f19a7c
   health: HEALTH_OK

 services:
   mon: 3 daemons, quorum a,b,c (age 3m)
   mgr: a(active, since 2m)
   osd: 3 osds: 3 up (since 1m), 3 in (since 1m)
...

Storage

有關 Rook 公開的三種儲存型別的演練,請參閱以下指南:

  • Block:建立要由 Pod 使用的塊(block)儲存
  • Object:建立可在 Kubernetes 叢集內部或外部訪問的物件儲存
  • Shared Filesystem:建立要在多個 pod 之間共享的檔案系統

Ceph 儀表板

Ceph 有一個儀表板,您可以在其中檢視叢集的狀態。

工具

我們建立了一個 toolbox 容器,其中包含用於除錯和排除 Rook 叢集故障的全套 Ceph 客戶端。

監控

每個 Rook 叢集都有一些內建的指標收集器(collectors)/匯出器(exporters),用於使用 Prometheus 進行監控。

銷燬

完成測試叢集后,請參閱這些說明以清理叢集。

網路檔案系統 (NFS)

NFS 允許遠端主機通過網路掛載檔案系統並與這些檔案系統互動,就像它們是在本地掛載一樣。這使系統管理員能夠將資源整合到網路上的中央伺服器上。

前提條件

  1. 執行 Rook NFS operator 需要 Kubernetes 叢集。
  2. 要暴露的卷,需要通過 PVC 附加到 NFS server pod。
    可以被附加(attached)和匯出(exported)任何型別的 PVC,例如 Host PathAWS Elastic Block StoreGCP Persistent DiskCephFSCeph RBD 等。
    這些卷的限制(limitations)在它們由 NFS 共享時也適用。您可以在 Kubernetes docs 中進一步瞭解這些卷的詳細資訊和限制。
  3. NFS client packages 必須安裝在 Kubernetes 可能執行掛載 NFS 的 pod 的所有節點上。在 CentOS 節點上安裝 nfs-utils 或在 Ubuntu 節點上安裝 nfs-common

部署 NFS Operator

首先使用以下命令部署 Rook NFS operator:

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

您可以檢查 operator 是否已啟動並執行:

kubectl -n rook-nfs-system get pod
NAME                                    READY   STATUS    RESTARTS   AGE
rook-nfs-operator-879f5bf8b-gnwht       1/1     Running   0          29m

部署 NFS Admission Webhook (可選)

Admission webhooks 是 HTTP 回撥,用於接收對 API 伺服器的准入請求。
兩種型別的 admission webhooks 是驗證 admission webhookmutating admission webhook
NFS Operator 支援驗證 admission webhook,它在儲存到 etcd(持久化)之前驗證傳送到 API serverNFSServer 物件。

要在 NFS 上啟用 admission webhook,例如驗證 admission webhook,您需要執行以下操作:

首先,確保安裝了 cert-manager。如果尚未安裝,您可以按照 cert-manager 安裝文件中的說明進行安裝。
或者,您可以簡單地執行以下單個命令:

kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.1/cert-manager.yaml

這將輕鬆安裝最新版本 (v0.15.1) 的 cert-manager。 完成後,確保 cert-manager 元件部署正確並處於 Running 狀態:

kubectl get -n cert-manager pod
NAME                                      READY   STATUS    RESTARTS   AGE
cert-manager-7747db9d88-jmw2f             1/1     Running   0          2m1s
cert-manager-cainjector-87c85c6ff-dhtl8   1/1     Running   0          2m1s
cert-manager-webhook-64dc9fff44-5g565     1/1     Running   0          2m1s

一旦 cert-manager 執行,您現在可以部署 NFS webhook

kubectl create -f webhook.yaml

驗證 webhook 已啟動並正在執行:

kubectl -n rook-nfs-system get pod
NAME                                    READY   STATUS    RESTARTS   AGE
rook-nfs-operator-78d86bf969-k7lqp      1/1     Running   0          102s
rook-nfs-webhook-74749cbd46-6jw2w       1/1     Running   0          102s

建立 Openshift 安全上下文約束(可選)

在 OpenShift 叢集上,我們需要建立一些額外的安全上下文約束。如果您未在 OpenShift 中執行,則可以跳過此部分並轉到下一部分

要為 nfs-server pod 建立安全上下文約束,我們可以使用以下 yaml,它也可以在 /cluster/examples/kubernetes/nfs 下的 scc.yaml 中找到。

注意:舊版本的 OpenShift 可能需要 apiVersion: v1

kind: SecurityContextConstraints
apiVersion: security.openshift.io/v1
metadata:
  name: rook-nfs
allowHostDirVolumePlugin: true
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegedContainer: false
allowedCapabilities:
- SYS_ADMIN
- DAC_READ_SEARCH
defaultAddCapabilities: null
fsGroup:
  type: MustRunAs
priority: null
readOnlyRootFilesystem: false
requiredDropCapabilities:
- KILL
- MKNOD
- SYS_CHROOT
runAsUser:
  type: RunAsAny
seLinuxContext:
  type: MustRunAs
supplementalGroups:
  type: RunAsAny
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- secret
users:
  - system:serviceaccount:rook-nfs:rook-nfs-server

您可以使用以下命令建立 scc:

oc create -f scc.yaml

建立 Pod 安全策略(推薦)

我們建議您也建立 Pod 安全策略

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: rook-nfs-policy
spec:
  privileged: true
  fsGroup:
    rule: RunAsAny
  allowedCapabilities:
  - DAC_READ_SEARCH
  - SYS_RESOURCE
  runAsUser:
    rule: RunAsAny
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  volumes:
  - configMap
  - downwardAPI
  - emptyDir
  - persistentVolumeClaim
  - secret
  - hostPath

使用名稱 psp.yaml 儲存此檔案並使用以下命令建立:

kubectl create -f psp.yaml

建立和初始化 NFS 伺服器

現在 operator 正在執行,我們可以通過建立 nfsservers.nfs.rook.io 資源的例項來建立 NFS 伺服器的例項。
NFS server resource 的各種欄位和選項可用於配置要匯出的伺服器及其卷。

在我們建立 NFS Server 之前,我們需要建立 ServiceAccountRBAC 規則

---
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

使用名稱 rbac.yaml 儲存此檔案並使用以下命令建立:

kubectl create -f rbac.yaml

本指南有 3 個主要示例,用於演示使用 NFS 伺服器匯出卷(exporting volumes):

  1. 預設 StorageClass 示例
  2. XFS StorageClass 示例
  3. Rook Ceph volume 示例

預設 StorageClass 示例

第一個示例將逐步建立一個 NFS server 例項,該例項匯出由您碰巧執行的環境的預設 StorageClass 支援的儲存。
在某些環境中,這可能是主機路徑(host path),在其他環境中,它可能是雲提供商虛擬磁碟(cloud provider virtual disk)。
無論哪種方式,此示例都需要存在預設的 StorageClass

首先將以下 NFS CRD 例項定義儲存到名為 nfs.yaml 的檔案中:

---
# A default storageclass must be present
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-default-claim
  namespace: rook-nfs
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: nfs.rook.io/v1alpha1
kind: NFSServer
metadata:
  name: rook-nfs
  namespace: rook-nfs
spec:
  replicas: 1
  exports:
  - name: share1
    server:
      accessMode: ReadWrite
      squash: "none"
    # A Persistent Volume Claim must be created before creating NFS CRD instance.
    persistentVolumeClaim:
      claimName: nfs-default-claim
  # A key/value list of annotations
  annotations:
    rook: nfs

儲存了 nfs.yaml 檔案後,現在建立 NFS server,如下所示:

kubectl create -f nfs.yaml

XFS StorageClass 示例

Rook NFS 通過 xfs_quota 支援磁碟配額。因此,如果您需要為卷指定磁碟配額,則可以按照此示例進行操作。

在這個例子中,我們將使用一個帶有 prjquota 選項的作為 xfs 掛載的底層卷。
在建立底層卷(underlying volume)之前,您需要使用 xfs 檔案系統和 prjquota mountOptions 建立 StorageClass
Kubernetes 的許多分散式儲存提供商都支援 xfs 檔案系統。
通常通過在 storageClass 引數中定義 fsType: xfsfs: xfs
但實際上如何指定 storage-class 檔案系統型別取決於它自己的儲存提供者。
您可以檢視 https://kubernetes.io/docs/concepts/storage/storage-classes/ 瞭解更多詳情。

這是 GCE PD 和 AWS EBS 的示例 StorageClass

  • GCE PD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard-xfs
parameters:
  type: pd-standard
  fsType: xfs
mountOptions:
  - prjquota
provisioner: kubernetes.io/gce-pd
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
  • AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard-xfs
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "10"
  fsType: xfs
mountOptions:
  - prjquota
reclaimPolicy: Delete
volumeBindingMode: Immediate

一旦您已經擁有帶有 xfs 檔案系統和 prjquota mountOptions 的 StorageClass,您就可以使用以下示例建立 NFS server 例項。

---
# A storage class with name standard-xfs must be present.
# The storage class must be has xfs filesystem type  and prjquota mountOptions.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-xfs-claim
  namespace: rook-nfs
spec:
  storageClassName: "standard-xfs"
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: nfs.rook.io/v1alpha1
kind: NFSServer
metadata:
  name: rook-nfs
  namespace: rook-nfs
spec:
  replicas: 1
  exports:
  - name: share1
    server:
      accessMode: ReadWrite
      squash: "none"
    # A Persistent Volume Claim must be created before creating NFS CRD instance.
    persistentVolumeClaim:
      claimName: nfs-xfs-claim
  # A key/value list of annotations
  annotations:
    rook: nfs

將此 PVC 和 NFS Server 例項儲存為 nfs-xfs.yaml 並使用以下命令建立。

kubectl create -f nfs-xfs.yaml

Rook Ceph volume 示例

在這個替代示例中,我們將使用不同的基礎卷(underlying volume)作為 NFS server 的 export。
這些步驟將引導我們匯出 Ceph RBD block volume,以便客戶端可以通過網路訪問它。

Rook Ceph 叢集啟動並執行後,我們可以繼續建立 NFS server

將此 PVC 和 NFS 伺服器例項儲存為 nfs-ceph.yaml

---
# A rook ceph cluster must be running
# Create a rook ceph cluster using examples in rook/cluster/examples/kubernetes/ceph
# Refer to https://rook.io/docs/rook/master/ceph-quickstart.html for a quick rook cluster setup
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-ceph-claim
  namespace: rook-nfs
spec:
  storageClassName: rook-ceph-block
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
---
apiVersion: nfs.rook.io/v1alpha1
kind: NFSServer
metadata:
  name: rook-nfs
  namespace: rook-nfs
spec:
  replicas: 1
  exports:
  - name: share1
    server:
      accessMode: ReadWrite
      squash: "none"
    # A Persistent Volume Claim must be created before creating NFS CRD instance.
    # Create a Ceph cluster for using this example
    # Create a ceph PVC after creating the rook ceph cluster using ceph-pvc.yaml
    persistentVolumeClaim:
      claimName: nfs-ceph-claim
  # A key/value list of annotations
  annotations:
    rook: nfs

建立您儲存在 nfs-ceph.yaml 中的 NFS server 例項:

kubectl create -f nfs-ceph.yaml

驗證 NFS Server

我們可以使用以下命令驗證是否已建立代表我們的新 NFS server 及其匯出的 Kubernetes 物件。

kubectl -n rook-nfs get nfsservers.nfs.rook.io
NAME       AGE   STATE
rook-nfs   32s   Running

驗證 NFS server pod 是否已啟動並正在執行:

kubectl -n rook-nfs get pod -l app=rook-nfs
NAME         READY     STATUS    RESTARTS   AGE
rook-nfs-0   1/1       Running   0          2m

如果 NFS server pod 處於 Running 狀態,那麼我們已經成功建立了一個暴露的 NFS 共享,客戶端可以開始通過網路訪問。

訪問 Export

從 Rook 版本 v1.0 開始,Rook 支援 NFS 的動態配置(dynamic provisioning)。此示例將展示如何將動態配置功能用於 nfs。

部署 NFS OperatorNFSServer 例項後。必須建立類似於以下示例的 storageclass 來動態配置卷。

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: nfs.rook.io/rook-nfs-provisioner
reclaimPolicy: Delete
volumeBindingMode: Immediate

您可以將其另存為檔案,例如:名為 sc.yaml 然後使用以下命令建立 storageclass

kubectl create -f sc.yaml

注意StorageClass 需要傳遞以下 3 個引數。

  1. exportName: 它告訴供應商(provisioner)使用哪個匯出來供應卷。
  2. nfsServerName: 它是 NFSServer 例項的名稱。
  3. nfsServerNamespace: NFSServer 例項執行所在的名稱空間。

建立上述 storageclass 後,您可以建立引用 storageclass 的 PV claim,如下面給出的示例所示。

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

您也可以將其儲存為檔案,例如:名為 pvc.yaml 然後使用以下命令建立 PV claim。

kubectl create -f pvc.yaml

消費 Export

現在我們可以通過建立一個示例 web server app 來使用剛剛建立的 PV,
該應用程式使用上述 PersistentVolumeClaim 宣告匯出的卷。有 2 個 pod 構成此示例:

  1. 將讀取和顯示 NFS 共享內容的 Web server pod
  2. 將隨機資料寫入 NFS 共享的 writer pod,以便網站不斷更新

cluster/examples/kubernetes/nfs 資料夾啟動 busybox pod(writer)和 web server:

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

讓我們確認預期的 busybox writer pod 和 Web server pod 都已啟動並處於 Running 狀態:

kubectl get pod -l app=nfs-demo

為了能夠通過網路訪問 Web server,讓我們為它建立一個 service:

kubectl create -f web-service.yaml

然後我們可以使用我們之前啟動的 busybox writer pod 來檢查 nginx 是否正確地提供資料。
在下面的 1-liner 命令中,我們使用 kubectl execbusybox writer pod 中執行一個命令,
該命令使用 wget 檢索 web server pod 託管的 web page。
隨著 busybox writer pod 繼續寫入新的時間戳,我們應該會看到返回的輸出也每大約 10 秒更新一次。

$ 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

清理銷燬

要清理與此演練相關的所有資源,您可以執行以下命令。

kubectl delete -f web-service.yaml
kubectl delete -f web-rc.yaml
kubectl delete -f busybox-rc.yaml
kubectl delete -f pvc.yaml
kubectl delete -f pv.yaml
kubectl delete -f nfs.yaml
kubectl delete -f nfs-xfs.yaml
kubectl delete -f nfs-ceph.yaml
kubectl delete -f rbac.yaml
kubectl delete -f psp.yaml
kubectl delete -f scc.yaml # if deployed
kubectl delete -f operator.yaml
kubectl delete -f webhook.yaml # if deployed
kubectl delete -f common.yaml

故障排除

如果 NFS server pod 沒有出現,第一步是檢查 NFS operator 的日誌:

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

相關文章