在 EKS 中使用 qtree 扩展 ONTAP 存储卷数量上限,实现千万 PVC 数量级持久化存储
日期: 2023-03-08

 

背景

 

目前,在已经上线 FSx for NetApp  ONTAP 文件存储服务的AWS各区域中,每个文件系统的卷上限为500个。在多租户场景需求中,客户通常需要创建数千或数万个小型的存储空间供给前端的容器使用,且要求存储空间必须互相隔离且具备配额功能。在此类场景中,对于读写性能的需求通常不会很高,但要求存储卷间数据隔离且支持配额。 FSx for NetApp ONTAP 可以很好的满足功能上的需求,但卷数量上限使得客户不得不寻求将业务数据分散在多套文件系统中或者考虑其他自建存储解决方案,推高运维成本。为了应对此类型的需求,可以使用qtree的方式扩展单个文件系统可支持的PVC数量上限,其优势有:

  • 将每个文件系统支持的PVC数量从500提升到10万
  • 将每个Amazon区域文件系统支持的PVC数量从5万提升到1000万
  • 通过存储超分配有效降低初期配置成本

 

 

相关概念

 

Amazon EKSAmazon Elastic Kubernetes Service (Amazon EKS) 是一项托管服务,可让您在 AWS 上轻松运行 Kubernetes,而无需安装、操作或维护您自己的 Kubernetes 控制面板或节点。Kubernetes 是一个用于实现容器化应用程序的部署、扩展和管理的自动化的开源系统。 Amazon FSx for NetApp ONTAPAmazon FSx for NetApp ONTAP 是一项完全托管的服务,它提供了基于 NetApp 流行的 ONTAP 文件系统构建的高度可靠、可扩展、高性能和全功能的文件存储。FSx for ONTAP 结合了熟悉的功能、性能、功能和 API 操作 NetApp 具有完全托管的灵活性、可扩展性和便捷性的文件系统AWS 服务。 Kubernetes CSI CSI 是容器编排引擎和存储系统间的一套标准的存储调用接口。Kubernetes API Server可以在不修改核心代码的情况下,通过套接字与第三方存储进行交互,以利用第三方存储。 TridentTrident是一个由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 NetApp ONTAP文件存储服务

在管理门户中选择FSx产品,点击Create File System以创建新的FSx文件存储服务(注:下面的截图来自于美国东部 AWS区域)

 

 

部署类型我们本次选择快速创建,此类型只需要指定容量、可用区、网络等少量关键信息即可完成创建工作。

注意点:

1. FSx for NetApp ONTAP最小配置大小为1024GB
2. 确保VPC要与EKS集群相同
3. 在生产环境中建议使用多可用区Multi-AZ类型并启用Storage Efficiency 以实现成本优化

 

 

等待文件系统创建完成,Lifecycle State的状态为:Available

 

 

确认 Amazon EKS 集群的可用状态

1. 再次确认EKS集群和FSx在同一个VPC
2. 确认当前EKS账号有权限创建k8s资源
3. 确认集群所有节点处于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是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都提供了哪些存储驱动选项:

 

 

 

其中:

– 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

 

{
“version”: 1,
“backendName”: “ExampleBackend”,
“storageDriverName”: “ontap-nas-economy”,
“managementLIF”: “<SVM管理地址>”,
“dataLIF”: “<SVM数据地址>”,
“svm”: “<SVM的名称>”,
“username”: “vsadmin”,
“password”: “xxxxxxxxxxxxxxx”,
}

 

 

确认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 NAME
SPACE
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:

 

$ ssh vsadmin@   

 

 

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 

 

 

启用此功能后,直接通过

 

$kubectl edit pvc                 

 

 

 

或者

 

$oc patch pvc

 

 

 

即可直接改变PVC的大小。以下测试案例创建了一个pod实现每5秒写一个时间戳信息到日志文件:

 

 

Version: 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://aws.amazon.com/cn/blogs/china/use-qtree-in-eks-to-extend-the-maximum-number-of-ontap-storage-volumes-to-achieve-10-million-pvcs-of-persistent-storage/]

作者:王志达