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