背景
目前,在已经上线 FSx for NetApp ONTAP 文件存储服务的 AWS 各区域中,每个文件系统的卷上限为 500 个。在多租户场景需求中,客户通常需要创建数千或数万个小型的存储空间供给前端的容器使用,且要求存储空间必须互相隔离且具备配额功能。在此类场景中,对于读写性能的需求通常不会很高,但要求存储卷间数据隔离且支持配额。FSx for NetApp ONTAP 可以很好的满足功能上的需求,但卷数量上限使得客户不得不寻求将业务数据分散在多套文件系统中或者考虑其他自建存储解决方案,推高运维成本。为了应对此类型的需求,可以使用 qtree 的方式扩展单个文件系统可支持的 PVC 数量上限,其优势有:
- 将每个文件系统支持的 PVC 数量从 500 提升到 10 万
- 将每个 Amazon 区域文件系统支持的 PVC 数量从 5 万提升到 1000 万
- 通过存储超分配有效降低初期配置成本
相关概念
Amazon EKS
Amazon Elastic Kubernetes Service(Amazon EKS)是一项托管服务,可让您在 AWS 上轻松运行 Kubernetes,而无需安装、操作或维护您自己的 Kubernetes 控制面板或节点。Kubernetes 是一个用于实现容器化应用程序的部署、扩展和管理的自动化的开源系统。
Amazon FSx for NetApp ONTAP
Amazon FSx for NetApp ONTAP 是一项完全托管的服务,它提供了基于 NetApp 流行的 ONTAP 文件系统构建的高度可靠、可扩展、高性能和全功能的文件存储。FSx for ONTAP 结合了熟悉的功能、性能、功能和 API 操作 NetApp 具有完全托管的灵活性、可扩展性和便捷性的文件系统 AWS 服务。
Kubernetes CSI
CSI 是容器编排引擎和存储系统间的一套标准的存储调用接口。Kubernetes API Server 可以在不修改核心代码的情况下,通过套接字与第三方存储进行交互,以利用第三方存储。
Trident
Trident 是一个由 NetApp 维护的开源项目。它的设计初衷是使用行业标准接口(如容器存储接口(CSI))帮助客户满足容器化应用程序的持久性存储需求。
Trident 作为 pod 部署在 Kubernetes 集群中,并为您的 Kubernetes 工作负载提供动态存储编排服务。它使容器化的应用程序能够快速、轻松地使用 NetApp 广泛产品组合中的持久存储,包括 ONTAP 线下和云端托管产品(如 FSx for NetApp ONTAP)。
NetApp qtree
Qtree 是一种以 volume 为根的逻辑文件系统,它可以将一个 volume 抽象成数百或数千个逻辑存储空间,提供给客户端使用。对于需求大量独立、隔离存储空间的场景中会发挥较大的作用。在 ONTAP 存储系统中,这些逻辑存储空间将被聚合为一个独立的 volume 进行展示和管理。
架构介绍
在多租户场景中,每个 Kubernetes Pod 挂载一个独立的 PVC。配合 Trident CSI,FSx for NetApp ONTAP 可以提供多种类型的存储资源,包括基于 NFS 的文件存储或 ISCSI 协议的块存储,均支持使用 qtree 来扩展 PV 的数量,默认每个 NFS 卷支持 200 个 qtree。由于使用了存储超配,需要使用 CloudWatch 对文件系统的整体用量进行监控,及时扩容以避免出现数据读写问题。
使用 StorageClass,开发团队或管理员可以实现 PVC 的动态部署,其过程可参考下图:
为什么选择 FSx for NetApp ONTAP
在基于容器的海量小存储卷,需求隔离,配额和超分配的共享存储场景中,使用 FSx for NetApp ONTAP 能提供最好的兼容性并支持最多的卷数量上限,其中:
- EFS 是基于 NFS 的共享存储服务,每个 PV 对应一个文件系统,支持 CSI 但无法设置配额。
- FSx for Lustre 是并行高性能存储服务,适用于高吞吐需求和高并发场景,如机器学习、大数据分析等,并不适用于此场景。
- FSx for OpenZFS 并未提供 CSI,批量部署 PV 时会增加复杂度。
存储服务 |
PV 隔离 |
PV 配额 |
支持 CSI |
存储超分配 |
单区域数量上限 |
EFS |
|
|
√ |
|
1000 个文件系统 |
FSx for Lustre |
|
|
√ |
|
100 个文件系统 |
FSx for ONTAP |
√ |
√ |
√ |
√ |
100 个文件系统 500 个卷/文件系统 |
FSx for OpenZFS |
√ |
√ |
|
|
100 个文件系统 100 个卷/文件系统 |
准备工作
创建 FSx for NetApp ONTAP 文件存储服务
在管理门户中选择 FSx 产品,点击 Create File System 以创建新的 FSx 文件存储服务(注:下面的截图来自于美国东部 AWS 区域)
部署类型我们本次选择快速创建,此类型只需要指定容量、可用区、网络等少量关键信息即可完成创建工作。
注意点:
- FSx for NetApp ONTAP 最小配置大小为 1024GB
- 确保 VPC 要与 EKS 集群相同
- 在生产环境中建议使用多可用区 Multi-AZ 类型并启用 Storage Efficiency 以实现成本优化
等待文件系统创建完成,Lifecycle State 的状态为:Available
确认 Amazon EKS 集群的可用状态
- 再次确认 EKS 集群和 FSx 在同一个 VPC
- 确认当前 EKS 账号有权限创建 k8s 资源
- 确认集群所有节点处于 Ready 的状态
[root@ip-10-100-100-43 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
ip-10-100-1-106.us-east-2.compute.internal Ready <none> 41h v1.22.12-eks-ba74326
ip-10-100-2-13.us-east-2.compute.internal Ready <none> 41h v1.22.12-eks-ba74326
ip-10-100-3-246.us-east-2.compute.internal Ready <none> 41h v1.22.12-eks-ba74326
配置步骤
在 Amazon EKS 集群中安装 Trident
Trident 是 ONTAP CSI 的管理工具,需要安装在可管理 EKS 的节点上。在 VPC 网络中要求既可以访问到 EKS API,也可以访问到存储服务。Trident 对于 Kubernetes 的版本有一定要求。如在 v21.07 版本中,需要对应 Kubernetes 1.17 – 1.22 版本,在过低或过高的 Kubernetes 集群中将无法正常完成安装操作。目前最新版本 22.10 已经可以支持 1.25 版本。本示例将采用 Kubernetes1.22 + Trident 21.07 版本进行演示。
有关最新的 Trident 和 Kubernetes 的兼容性信息,可以参考:https://github.com/NetApp/trident/releases
部署 Trident 有两种方式,Helm 或命令行,本次我们采用命令行的方式进行手动部署。
第一步:下载 Trident Installer
$ wget https://github.com/NetApp/trident/releases/download/v21.07.2/trident-installer-21.07.2.tar.gz
$ tar -xf trident-installer-21.07.2.tar.gz
第二步:在 EKS 中创建 Trident 所需的 CRD
$ cd trident-installer
$ kubectl create -f
deploy/crds/trident.NetApp.io_tridentorchestrators_crd_post1.16.yaml
第三步:部署 Trident Operator
$ kubectl apply -f deploy/namespace.yaml
$ kubectl create -f deploy/bundle.yaml
$ kubectl get pod -n trident
NAME READY STATUS RESTARTS AGE
trident-operator-846d8f5598-vfb2v 1/1 Running 0 40h
$ kubectl create -f deploy/crds/tridentorchestrator_cr.yaml
tridentorchestrator.trident.NetApp.io/trident created
确保以下输出的 Status 值为:Installed
$ kubectl describe torc trident
Name: tridentNamespace:
Labels: Annotations:
API Version: trident.NetApp.io/v1
Kind: TridentOrchestrator
Metadata:
Creation Timestamp: 2022-10-18T12:11:21Z
Generation: 1
Resource Version: 20754
UID: c2e8cfd7-f5d5-4355-ab90-a7a17c6a719f
Spec:
Debug: true
Namespace: trident
Status:
Current Installation Params:
IPv6: false
Autosupport Hostname:
Autosupport Image: NetApp/trident-autosupport:21.01
Autosupport Proxy:
Autosupport Serial Number:
Debug: true
Enable Node Prep: false
Image Pull Secrets:
Image Registry:
k8sTimeout: 30
Kubelet Dir: /var/lib/kubelet
Log Format: text
Probe Port: 17546
Silence Autosupport: false
Trident Image: NetApp/trident:21.07.2
Message: Trident installed
Namespace: trident
Status: Installed
Version: v21.07.2
Events:
再次查看 namespace 下的 pod 信息,确保所有 pod 在 running 的状态:
$ kubectl get pod -n trident
NAME READY STATUS RESTARTS AGE
trident-csi-55987877-5xjq8 6/6 Running 0 40h
trident-csi-9bglv 2/2 Running 0 40h
trident-csi-dtmhk 2/2 Running 0 40h
trident-csi-tpfgn 2/2 Running 0 40h
trident-operator-846d8f5598-vfb2v 1/1 Running 0 40h
通过下面的命令确认 Trident 服务器端和客户端的状态和版本:
$ ./tridentctl -n trident version
+----------------+----------------+
| SERVER VERSION | CLIENT VERSION |
+----------------+----------------+
| 21.07.2 | 21.07.2 |
+----------------+----------------+
至此 Trident CSI 的安装操作完成,接下来就可以开始为 EKS 连接 FSx for NetApp ONTAP 存储了。如果相关 CSI 容器状态异常,可按照此文档进行问题排查:https://NetApp-trident.readthedocs.io/en/stable-v21.07/kubernetes/deploying/operator-deploy.html#observing-the-status-of-the-operator
Trident 后端存储服务选择和配置
在为 EKS 连接到存储服务前,我们需要了解 ONTAP 都提供了哪些存储驱动选项:
Driver |
Protocol |
VolumeMode |
Access Modes Supported |
File Systems Supported |
ontap-nas |
NFS |
Filesystem |
RWO,RWX,ROX |
nfs |
ontap-nas-economy |
NFS |
Filesystem |
RWO,RWX,ROX |
nfs |
ontap-san |
iSCSI |
Block |
RWO,ROX,RWX |
Raw block device |
ontap-san-economy |
iSCSI |
Block |
RWO,ROX,RWX |
Raw block device |
ontap-san |
iSCSI |
Filesystem |
RWO,ROX |
xfs, ext3, ext4 |
ontap-san-economy |
iSCSI |
Filesystem |
RWO,ROX |
xfs, ext3, ext4 |
其中:
- ontap-nas 和 ontap-nas-economy 选项使用标准 NFS 协议
- ontap-san 和 ontap-economy 选项使用 ISCSI 协议,支持提供裸卷或文件系统
- 带有“xxx-economy”的选项将启用 ONTAP qtree 功能
本次示例中将展示 ontap-nas-economy 这种文件系统选项,使用 NFS 协议挂载给容器。该选项将启用 qtree,实现默认 200 个 qtree 映射到一个 ONTAP 卷。这意味着这一个 ONTAP 卷就可以创建 200 个独立且相互隔离的的 PV 存储资源,而一个 FSx for NetApp ONTAP 将最多可提供 10 万个隔离的 PVC 给到容器平台使用。
每个连接到 Trident 的 ONTAP 被称为 backend,使用 json 格式的配置文件,其中包含几个关键配置信息:
{
"version": 1,
"backendName": "ExampleBackend",
"storageDriverName": "ontap-nas-economy",
"managementLIF": "<SVM 管理地址>",
"dataLIF": "<SVM 数据地址>",
"svm": "<SVM 的名称>",
"username": "vsadmin",
"password": "xxxxxxxxxxxxxxx",
}
这些信息需要从 FSx for NetApp ONTAP 的 SVM 配置中获取,分别对应:
- ManagementLIF – Management DNS Name 或 Manage IP address
- DataLIF – NFS DNS Name 或 NFS IP address
下面的 username 和 password 在 FSx for NetApp ONTAP 创建好后需要配置和更新。在 SVM 页面的右上角点击“Update”按钮,输入新的管理员账户和密码来完成密码的更新操作。
Trident 连接到 Amazon FSx for NetApp ONTAP
编辑好 backend.json 配置文件后,使用如下命令创建新的 Backup
$ tridentctl create backend -f cert-backend.json -n trident
$ tridentctl get backend -n trident
创建 StorageClass 和 PVC
StorageClass 的配置文件:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: basic
provisioner: csi.trident.NetApp.io
parameters:
backendType: "ontap-nas-economy"
allowVolumeExpansion: true
为了测试该模式下是否支持超过 500 个 PV,使用以下的 shell 脚本批量创建 600 个 PVC
for i in {1..600}; do
cat <<EOF | kubectl create -f -
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: trident-pvc-${i}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
storageClassName: basic
EOF
done
确认 PVC 的数量和状态:
$ kubectl get pvc | grep trident |wc -l
600
$ kubectl get pvc | grep trident
…
trident-pvc-590 Bound pvc-1f7779c5-beb6-43c6-b50e-fdeda585edf3 500Mi RWO basic 2d12h
trident-pvc-591 Bound pvc-97650edd-6b67-4f96-880d-cbd28a6893d2 500Mi RWO basic 2d12h
trident-pvc-592 Bound pvc-7a92d53c-4155-4644-97c6-df25ae5bd6c8 500Mi RWO basic 2d12h
trident-pvc-593 Bound pvc-1448cb28-09a9-4cb0-bf66-6b3702c0ac2a 500Mi RWO basic 2d12h
trident-pvc-594 Bound pvc-98917202-5788-4959-b7c9-ef86f091d25d 500Mi RWO basic 2d12h
trident-pvc-595 Bound pvc-8e173cfb-e217-47f3-98ff-1fdbd8c4a949 500Mi RWO basic 2d12h
trident-pvc-596 Bound pvc-17b349bb-103a-4de2-96bb-7dc1d44d8764 500Mi RWO basic 2d12h
trident-pvc-597 Bound pvc-39653587-3328-4652-afad-672a2e441025 500Mi RWO basic 2d12h
trident-pvc-598 Bound pvc-53103e41-f601-40bd-b70a-0dff479ada59 500Mi RWO basic 2d12h
trident-pvc-599 Bound pvc-97edcd6b-25ef-4825-9960-ff39a10fb8bf 500Mi RWO basic 2d12h
trident-pvc-6 Bound pvc-11b53d5f-7b57-44a5-94f0-40c8f5955a51 500Mi RWO basic 2d12h
trident-pvc-60 Bound pvc-107b1ca2-c067-44d5-a0c0-d5df413aab10 500Mi RWO basic 2d12h
…
从 FSx for NetApp ONTAP 看,共创建了 3 个卷,每个映射 200 个 qtree,总大小约 100GB(500MB*200 个),与预期的数量一致:
至此,我们已经实现通过 qtree 创建超过 500 个 PV。这使得单个 FSx for NetApp ONTAP 支持的最大 PV 数量获得了极大的扩展。
如何获得 PVC 的使用状况:
在日常运维过程中,我们经常需要监控存储的使用状况。在 qtree 场景中,每个 qtree 的详细用量和大小信息只能在 ONTAP 管理虚拟机中通过命令行或者 Rest API 获取,无法通过 CloudWatch 或 FSx 集成的界面查询,因此我们需要一种方式可以列出和查询每个 qtree PV 的用量信息,方法如下:
方法一: 使用 df-pv 获取 pv 的用量信息
使用 kubectl 插件管理工具 krew 安装 df-pv
$ kubectl krew install df-pv
使用如下命令查看每个 PVC 的绑定以及用量情况。如输出中第一个 PVC:nas-trident-11 的用量为 640KB,总量为 1024MB,绑定到的 Pod 是 trident-app-11。
$ kubectl df-pv -n default
PV NAME PVC NAME NAMESPACE NODE NAME POD NAME VOLUME MOUNT NAME SIZE USED AVAILABLE %USED IUSED IFREE %IUSED
pvc-b1d6a85f-be92-48d1-987d-70e6cf27821b nas-trident-11 default ip-10-100-3-79.us-east-2.compute.internal trident-app-11 persistent-storage 1024Mi 640Ki 1023Mi 0.06 97 31025 0.31
pvc-2af53cd5-dedf-43a4-8ee1-c2a8c8d60bb6 nas-trident-12 default ip-10-100-2-13.us-east-2.compute.internal trident-app-12 persistent-storage 1024Mi 576Ki 1023Mi 0.05 97 31025 0.31
pvc-19a87a37-f268-4093-8c33-71413ccec84a nas-trident-4 default ip-10-100-3-79.us-east-2.compute.internal trident-app-4 persistent-storage 1024Mi 576Ki 1023Mi 0.05 97 31025 0.31
pvc-bc69d594-a18c-4136-a9f1-7463ea188ae1 nas-trident-10 default ip-10-100-2-13.us-east-2.compute.internal trident-app-10 persistent-storage 1024Mi 576Ki 1023Mi 0.05 97 31025 0.31
pvc-af3134a7-cf43-465f-b59f-b348e020bb58 nas-trident-7 default ip-10-100-3-79.us-east-2.compute.internal trident-app-7 persistent-storage 1024Mi 768Ki 1023Mi 0.07 97 31025 0.31
pvc-730160bc-b319-4500-b829-71ab39becefe nas-trident-6 default ip-10-100-3-79.us-east-2.compute.internal trident-app-6 persistent-storage 1024Mi 640Ki 1023Mi 0.06 97 31025 0.31
pvc-3f1f4065-74bb-49ad-b64c-7982f77807c2 nas-trident-2 default ip-10-100-3-79.us-east-2.compute.internal trident-app-2 persistent-storage 1024Mi 640Ki 1023Mi 0.06 97 31025 0.31
pvc-a6da688d-e665-4d8d-ac4b-ee863573521d nas-trident-3 default ip-10-100-3-79.us-east-2.compute.internal trident-app-3 persistent-storage 1024Mi 640Ki 1023Mi 0.06 97 31025 0.31
pvc-1924b485-20e8-4140-befa-2f1ded345e7e nas-trident-9 default ip-10-100-3-79.us-east-2.compute.internal trident-app-9 persistent-storage 1024Mi 576Ki 1023Mi 0.05 97 31025 0.31
pvc-80e44481-232a-4186-ad7c-d7d11e25f673 nas-trident-8 default ip-10-100-3-79.us-east-2.compute.internal trident-app-8 persistent-storage 1024Mi 640Ki 1023Mi 0.06 97 31025 0.31
pvc-2bde216d-28ff-46bb-9818-4c3343246bfa nas-trident-5 default ip-10-100-3-79.us-east-2.compute.internal trident-app-5 persistent-storage 1024Mi 640Ki 1023Mi 0.06 97 31025 0.31
pvc-7b31616f-eb22-4419-8c1c-a0dadb9a6d1b nas-trident-1 default ip-10-100-3-79.us-east-2.compute.internal trident-app-1 persistent-storage 1024Mi 576Ki 1023Mi 0.05 97 31025 0.31
方法二:通过部署 Prometheus 到 EKS 集群,查寻下列指标获取:
- 使用量: kubelet_volume_stats_used_bytes
- 大小: kubelet_volume_stats_capacity_bytes
- 剩余容量: kubelet_volume_stats_available_bytes
方法三:使用 ONTAP volume quota
在方法一和方法二中可以列出的是正在使用的 PVC 用量信息,如果需要在 PVC 被容器释放后仍然可以查询到其信息,可以在 ONTAP 的管理虚拟机 SVM 中为 qtree 启用 quota,实现在存储侧监控使用状况。操作步骤如下:
1.SSH 登录到 ONTAP SVM:
2.为 volume 配置quota:
$ quota policy rule create \
-vserver fsx -policy-name qtree_policy_0 \
-volume trident_qtree_pool_trident_HHMNSUFVCR \
-type tree \
-target "" \
-soft-disk-limit –
3.获取 quota 的 report:
qtree/volume 动态扩容
独立的存储空间都有固定的容量上限,在容量不够的情况下需要进行扩容。
ONTAP Trident CSI 支持存储的在线扩容功能,启用此功能需要在 StorageClass 里添加一行:
allowVolumeExpansion: true
启用此功能后,直接通过
或者
即可直接改变 PVC 的大小。以下测试案例创建了一个 pod 实现每 5 秒写一个时间戳信息到日志文件:
apiVersion: v1
kind: Pod
metadata:
name: ex-test-app
spec:
containers:
- name: ontap-app
image: centos
command: ["/bin/sh"]
args: ["-c", "while true; do echo $(date -u) >> /data/ex-ontap.txt; sleep 5; done"]
volumeMounts:
- name: ex-trident
mountPath: /data
volumes:
- name: ex-trident
persistentVolumeClaim:
claimName: ex-trident-1
确认 PV 的存储空间已经扩容:
$ kubectl exec ex-test-app -- df -Th | grep nfssvm-040955f6f528a79ee.fs-00faa123b0c42cc68.fsx.us-east-2.amazonaws.com:/trident_qtree_pool_trident_VJXEUTKFRF/trident_pvc_e0f23ad1_16cb_49d2_8a93_a3dbc7a92567 nfs4 500M 0 500M 0% /data
$ kubectl exec ex-test-app -- df -Th | grep nfs
svm-040955f6f528a79ee.fs-00faa123b0c42cc68.fsx.us-east-2.amazonaws.com:/trident_qtree_pool_trident_VJXEUTKFRF/trident_pvc_e0f23ad1_16cb_49d2_8a93_a3dbc7a92567 nfs4 4.9G 0 4.9G 0% /data
通过查看容器的状态和日志,可以看到容器并没有发生重启,日志文件也没有被清空:
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
ex-test-app 1/1 Running 0 40m
$ kubectl exec ex-test-app -- cat /data/ex-ontap.txt
Mon Oct 24 01:57:03 UTC 2022
Mon Oct 24 01:57:08 UTC 2022
Mon Oct 24 01:57:13 UTC 2022
Mon Oct 24 01:57:18 UTC 2022
Mon Oct 24 01:57:23 UTC 2022
Mon Oct 24 01:57:28 UTC 2022
Mon Oct 24 01:57:33 UTC 2022
Mon Oct 24 01:57:38 UTC 2022
Mon Oct 24 01:57:43 UTC 2022
Mon Oct 24 01:57:48 UTC 2022
Mon Oct 24 01:57:53 UTC 2022
Mon Oct 24 01:57:58 UTC 2022
Mon Oct 24 01:58:03 UTC 2022
Mon Oct 24 01:58:08 UTC 2022
Mon Oct 24 01:58:13 UTC 2022
Mon Oct 24 01:58:18 UTC 2022
Mon Oct 24 01:58:23 UTC 2022
Mon Oct 24 01:58:28 UTC 2022
Mon Oct 24 01:58:33 UTC 2022
Mon Oct 24 01:58:38 UTC 2022
Mon Oct 24 01:58:43 UTC 2022
Mon Oct 24 01:58:48 UTC 2022
以上就是有关在 EKS 中使用 qtree 扩展 ONTAP PV 数量的有关内容。通过该解决方案,客户可获得如下的收益:
- 高可用的托管文件系统提供稳定的存储资源,降低运维成本
- 将每个文件系统支持的 PVC 数量从 500 提升到 10 万
- 将每个区域的文件系统支持的 PVC 数量从 5 万提升到 1000 万
- 每个 PVC 支持独立配额并可以动态扩容以适应多租户多级场景需求
- 通过存储超分配有效降低初期配置成本
参考资料
https://NetApp-trident.readthedocs.io/en/latest/support/requirements.html
https://NetApp-trident.readthedocs.io/en/latest/kubernetes/fsx.html
https://library.NetApp.com/ecmdocs/ECMP1154894/html/GUID-05E060D3-AF1B-48D5-87E7-437D87716478.html
https://docs.thinkwithwp.com/fsx/latest/ONTAPGuide/what-is-fsx-ontap.html
https://docs.thinkwithwp.com/eks/latest/userguide/fsx-ontap.html
本篇作者