使用CNFS管理CPFS通用版动态存储卷

ACK中,通过CNFS可将一个共享的CPFS通用版文件系统,以动态存储卷的方式为应用提供存储。配置StorageClass后,工作负载可自动获得基于CPFS隔离子目录的独立PV,从而实现数据隔离,并简化存储管理。

前提条件

  • 根据集群版本,完成以下条件。

    如需升级集群,请参见升级集群

    1.26及以上

    1.26以下

    • 确保CSI组件版本为v1.24.11-5221f79-aliyun及以上。

      如需升级CSI组件,请参见管理csi-plugincsi-provisioner组件
    • 已安装客户端依赖并重启csi-plugin组件。

      展开查看操作步骤

      需配置csi-pluginConfigMap,使得csi-plugin启动时自动安装客户端依赖。

      1. 检查是否存在名为csi-pluginConfigMap。

        kubectl -n kube-system get cm csi-plugin

        存在

        如果已有名为csi-pluginConfigMap,更新该ConfigMap。

        kubectl edit configmap csi-plugin -n kube-system

        data下新增cnfs-client-properties字段,并配置cpfs-efc=true以安装客户端依赖。

        ...
        data:
          cnfs-client-properties: |
            cpfs-efc=true   # csi-plugin启动时会安装相关依赖。

        不存在

        如果没有名为csi-pluginConfigMap,在kube-system命名空间下创建ConfigMap。

        cat <<EOF | kubectl apply -f -
        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: csi-plugin
          namespace: kube-system
        data:
          cnfs-client-properties: |
            cpfs-efc=true   # csi-plugin启动时会安装相关依赖。
        EOF
      2. 重启csi-plugin组件。

        kubectl -n kube-system rollout restart daemonset csi-plugin
  • 已创建与集群处于同一VPC下的CPFS通用版文件系统和对应的协议服务,并获取挂载点地址,请参见创建协议服务并获取挂载地址

    建议CPFS的协议服务挂载点和集群处于同一交换机下,以提升使用性能。

步骤一:使用NFS客户端挂载CPFS文件系统

  1. 参考以下内容,创建一个CNFS托管CPFS文件系统。

    以下命令将创建一个CNFS和一个StorageClass,通过CNFS隔离卷方式使用NFS客户端挂载CPFS文件系统。

    cat << EOF | kubectl apply -f -
    apiVersion: storage.alibabacloud.com/v1beta1
    kind: ContainerNetworkFileSystem
    metadata:
      name: cnfs-nfs-cpfs
    spec:
      type: cpfs
      reclaimPolicy: Retain
      parameters:
        protocolServer: cpfs-xxxx.xxxx.cpfs.aliyuncs.com # 填写CPFS的协议服务的挂载点域名。
        useClient: NFSClient  # 使用NFS客户端进行挂载。
    ---
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: cnfs-nfs-cpfs-sc
    mountOptions:
      - nolock,tcp,noresvport
      - vers=3
    parameters:
      volumeAs: subpath
      containerNetworkFileSystem: "cnfs-nfs-cpfs"  # 引用创建的CNFS对象cnfs-nfs-cpfs。
      path: "/share"
      archiveOnDelete: "true"
    provisioner: nasplugin.csi.alibabacloud.com
    reclaimPolicy: Retain
    allowVolumeExpansion: true
    EOF
    • CNFS

      参数

      说明

      type

      需要创建的存储卷类型。本示例为cpfs

      reclaimPolicy

      回收策略。仅支持Retain,删除CNFS时并不会删除CPFS文件系统。

      parameters

      protocolServer

      填写CPFS通用版文件系统的协议服务的挂载点域名。

      useClient

      配置为NFSClient,表示使用NFS客户端进行挂载。

    • StorageClass

      参数

      说明

      mountOptions

      挂载参数。默认参考本文示例即可。

      parameters

      volumeAs

      设置为subpath,表示创建子目录类型的PV。

      containerNetworkFileSystem

      关联的CNFS的名称。

      path

      CPFS通用版协议服务导出目录对应路径,例如/share。支持设置为子目录,例如/share/dir

      目前仅支持普通目录,不支持Fileset

      parameters.archiveOnDelete

      删除PVC时,若reclaimPolicyDelete,后端存储的文件数据是否被真正删除。

      CPFS通用版为共享存储,提供此选项进行双重确认。
      • true(默认):不会真正删除目录或文件,而是将其归档并重命名,格式为archived-{pvName}.{timestamp}

      • false:后端对应的目录及数据会被真正删除。

        此处删除的是CPFSsubpath目录以及其中文件,CPFS本身不会被删除。

        如需删除CPFS,请参见删除文件系统

      reclaimPolicy

      PV的回收策略。

      • Delete:删除PVC时,根据archiveOnDelete的配置处理后端存储数据。

      • Retain:删除PVC时,PVCPFS不会被删除,需手动删除。适用于对数据安全性要求高的场景,以免误删数据。

      allowVolumeExpansion

      可选参数。表示允许扩容CPFS存储卷。

  2. 参考以下内容,创建一个名为cnfs-nfs-cpfs-stsStatefulSet并挂载CPFS隔离存储卷。

    cat << EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: cnfs-nfs-cpfs-sts
    spec:
      selector:
        matchLabels:
          app: nginx
      serviceName: "nginx"
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            volumeMounts:
            - name: pvc
              mountPath: /data
      volumeClaimTemplates:
      - metadata:
          name: pvc
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "cnfs-nfs-cpfs-sc"     # 绑定的StorageClass名称。 
          resources:
            requests:
              storage: 50Gi
    EOF
  3. 查看CNFS状态。

    kubectl get cnfs cnfs-nfs-cpfs -o jsonpath='{.status.status}' 

    预期返回如下,状态为Available表示CNFS可用。

    Available
  4. 查看PVC状态。

    kubectl get pvc -o wide | grep cnfs-nfs-cpfs-sc

    预期返回如下,已自动创建2PVC,并绑定了自动创建的PV。

    pvc-cnfs-nfs-cpfs-sts-0   Bound    nas-804e8cb1-2355-4026-87fc-ee061e14f5f9   50Gi       RWO            cnfs-nfs-cpfs-sc   <unset>                 5m36s   Filesystem
    pvc-cnfs-nfs-cpfs-sts-1   Bound    nas-00baf7ff-75dc-440d-bab1-ea8872f1adea   50Gi       RWO            cnfs-nfs-cpfs-sc   <unset>                 5m25s   Filesystem
  5. 查看Pod状态。

    kubectl get pod | grep cnfs-nfs-cpfs-sts

    预期返回:

    NAME                  READY   STATUS    RESTARTS   AGE
    cnfs-nfs-cpfs-sts-0   1/1     Running   0          9m22s
    cnfs-nfs-cpfs-sts-1   1/1     Running   0          9m11s
  6. 确认Pod已挂载CPFS存储卷。

    kubectl exec cnfs-nfs-cpfs-sts-0 -- mount | grep nfs

    预期返回如下,表示CNFS使用NFS客户端已成功挂载CPFS文件系统。

    cpfs-********-********.cn-shanghai.cpfs.aliyuncs.com:/share/nas-804e8cb1-2355-4026-87fc-ee061e14f5f9 on /data type nfs (rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,noresvport,proto=tcp,port=30000,timeo=600,retrans=2,sec=sys,mountaddr=127.0.1.255,mountvers=3,mountport=30000,mountproto=tcp,local_lock=all,addr=127.0.1.255)

步骤二:验证存储卷是否相互隔离

  1. 1G的临时文件写入其中一个名称为cnfs-xxx-cpfs-sts-0Pod中,并查看是否写入成功。

    请使用实际Pod名称替换cnfs-xxx-cpfs-sts-0

    kubectl exec cnfs-xxx-cpfs-sts-0 -- sh -c "dd if=/dev/zero of=/data/1G.tmpfile bs=1G count=1;ls -alrth /data"

    预期返回:

    1+0 records in
    1+0 records out
    1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.2487 s, 477 MB/s
    total 1.1G
    drwxr-xr-x 1 root root 4.0K Aug  5 08:46 ..
    drwxr-xr-x 2 root root 4.0K Aug  5 09:10 .
    -rw-r--r-- 1 root root 1.0G Aug  5 09:10 1G.tmpfile
  2. 在名称为cnfs-xxx-cpfs-sts-1Pod中,确认并不存在1G的临时文件。

    请使用实际Pod名称替换cnfs-xxx-cpfs-sts-1

    kubectl exec cnfs-xxx-cpfs-sts-1 -- sh -c "ls -alrth /data"

    预期返回如下,在名称为cnfs-xxx-cpfs-sts-1Pod中并不存在1G的临时文件,即StatefulSet中的2Pod所使用的存储卷相互隔离。

    total 4.5K
    drwxr-xr-x 2 root root 4.0K Aug  5 08:46 .
    drwxr-xr-x 1 root root 4.0K Aug  5 08:46 ..