评论

收藏

[C++] 快速上手 Rook,入门云原生存储编排

编程语言 编程语言 发布于:2021-08-09 23:10 | 阅读数:493 | 评论:0

DSC0000.png

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,请将 rack 的 Spec.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,请将 rack 的 Spec.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。
前提条件
为确保您拥有可用于 Rook 的 Kubernetes 集群。
为了配置 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 之前,您可能需要考虑一些设置:

  • 如果您使用 kubernetes v1.15 或更早版本,则需要在此处创建 CRD,在 /cluster/examples/kubernetes/ceph/pre-k8s-1.16/crd.yaml。
    CustomResourceDefinition 的 apiextension v1beta1 版本在 Kubernetes v1.16 中已弃用。
  • 考虑是否要启用默认禁用的某些 Rook 功能。有关这些和其他高级设置,请参阅 operator.yaml。

    • 设备发现:如果启用了 ROOK_ENABLE_DISCOVERY_DAEMON 设置,Rook 将监视要配置的新设备,常用于裸机集群。
    • Flex driver:Flex driver 已被弃用,取而代之的是 CSI driver,但仍可通过 ROOK_ENABLE_FLEX_DRIVER 设置启用。
    • 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 允许远程主机通过网络挂载文件系统并与这些文件系统交互,就像它们是在本地挂载一样。这使系统管理员能够将资源整合到网络上的中央服务器上。
前提条件

  • 运行 Rook NFS operator 需要 Kubernetes 集群。
  • 要暴露的卷,需要通过 PVC 附加到 NFS server pod。
    可以被附加(attached)和导出(exported)任何类型的 PVC,例如 Host Path、AWS Elastic Block Store、GCP Persistent Disk、CephFS、Ceph RBD 等。
    这些卷的限制(limitations)在它们由 NFS 共享时也适用。您可以在 Kubernetes docs 中进一步了解这些卷的详细信息和限制。
  • 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 webhook 和 mutating admission webhook。
NFS Operator 支持验证 admission webhook,它在存储到 etcd(持久化)之前验证发送到 API server 的 NFSServer 对象。
要在 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 之前,我们需要创建 ServiceAccount 和 RBAC 规则
---
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):

  • 默认 StorageClass 示例
  • XFS StorageClass 示例
  • 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: xfs 或 fs: 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 Operator 和 NFSServer 实例后。必须创建类似于以下示例的 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 个参数。

  • exportName: 它告诉供应商(provisioner)使用哪个导出来供应卷。
  • nfsServerName: 它是 NFSServer 实例的名称。
  • 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 构成此示例:

  • 将读取和显示 NFS 共享内容的 Web server pod
  • 将随机数据写入 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 exec 在 busybox 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

关注下面的标签,发现更多相似文章