使用CNFS管理CPFS隔离存储卷

为提升CPFS文件系统的性能,容器服务ACK支持使用CNFS(Container Network File System)托管CPFS文件系统,对文件系统层独立管理。本文介绍如何通过CNFS的隔离存储卷方式,挂载NFS和EFC客户端使用CPFS文件系统。

索引

前提条件

  • 已创建Kubernetes集群,Kubernetes版本为v1.20及以上,且存储插件选择为CSI。具体操作,请参见创建ACK托管集群

  • 已确保CSI-Plugin和CSI-Provisioner组件版本为v1.24.11-5221f79-aliyun及以上。关于升级CSI-Plugin和CSI-Provisioner组件的操作,请参见管理CSI组件

  • 已确保storage-operator组件版本为v1.24.105-825188d-aliyun及以上。关于升级storage-operator组件的操作,请参见管理组件

  • 已通过kubectl工具连接Kubernetes集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群

  • 已创建CPFS文件系统和对应的协议服务,并获取挂载点地址。具体操作,请参见创建文件系统创建协议服务并获取挂载地址

    重要
    • 创建的CPFS文件系统和集群必须在同一VPC下。

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

步骤一:安装客户端依赖并重启CSI-Plugin组件

  1. 执行以下命令,查看集群中是否存在名为csi-plugin的ConfigMap。

    kubectl get configmap csi-plugin -nkube-system

    预期输出:

    NAME         DATA   AGE
    csi-plugin   X      6d22h
  2. 执行以下命令,对名称为csi-plugin的ConfigMap进行更新操作。

    kubectl edit configmap csi-plugin -nkube-system
  3. 执行以下命令,在ConfigMap文件中新增cnfs-client-properties字段,并安装客户端依赖。

    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
  4. 执行以下命令,重启CSI-Plugin组件。

    kubectl -n kube-system rollout restart daemonset csi-plugin

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

使用NFS客户端挂载CPFS文件系统

  1. 使用以下YAML文件,创建一个CNFS托管CPFS文件系统,通过CNFS的隔离卷方式使用NFS客户端挂载CPFS文件系统,同时将隔离存储卷绑定到工作负载StatefulSet中。

    展开查看所需的YAML文件

    # 创建CNFS、StorageClass和StatefulSet对象。
    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"
    provisioner: nasplugin.csi.alibabacloud.com
    reclaimPolicy: Delete
    allowVolumeExpansion: true
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: cnfs-nfs-cpfs-sts
    spec:
      selector:
        matchLabels:
          app: busybox
      serviceName: "busybox"
      replicas: 2
      template:
        metadata:
          labels:
            app: busybox
        spec:
          containers:
          - name: busybox
            image: busybox
            command: ["/bin/sh"]
            args: ["-c", "sleep 3600;"]
            volumeMounts:
            - name: pvc
              mountPath: /data
      volumeClaimTemplates:
      - metadata:
          name: pvc
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "cnfs-nfs-cpfs-sc"
          resources:
            requests:
              storage: 50Gi
    EOF
  2. 执行以下命令,查看CNFS是否为可用状态。

    kubectl get cnfs cnfs-nfs-cpfs -oyaml | grep status

    预期输出:

    status:
        status: Ready
      status: Available

    预期输出表明,CNFS状态为Available可用状态。

  3. 执行以下命令,查看PVC是否为绑定状态。

    kubectl get pvc -owide | grep cnfs-nfs-cpfs-sc

    预期输出:

    pvc-cnfs-nfs-cpfs-sts-0   Bound    nas-38727f0c-58c7-40df-b2e2-80537fcd74ae   50Gi       RWO            cnfs-nfs-cpfs-sc   66s     Filesystem
    pvc-cnfs-nfs-cpfs-sts-1   Bound    nas-ead04f09-ca37-408c-a50d-17e609fd48cf   50Gi       RWO            cnfs-nfs-cpfs-sc   4m50s   Filesystem

    预期输出表明,PVC状态为Bound绑定状态。

  4. 执行以下命令,查看Pod是否为运行状态。

    kubectl get sts cnfs-nfs-cpfs-sts -owide

    预期输出:

    NAME                READY   AGE   CONTAINERS   IMAGES
    cnfs-nfs-cpfs-sts   2/2     98s   busybox      busybox
  5. 执行以下命令,查看其中一个Pod是否挂载成功。

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

    预期输出:

    cpfs-03129888b1d5c6e7-031b038b4345e7cen.cn-beijing.cpfs.aliyuncs.com:/share/nas-e223798f-dccc-4453-be19-72140884f642 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)

    预期输出表明,CNFS使用NFS客户端已成功挂载CPFS文件系统。

使用EFC客户端挂载CPFS文件系统

  1. 使用以下YAML文件,创建一个CNFS托管CPFS文件系统,通过CNFS的隔离卷方式使用EFC客户端挂载CPFS文件系统,同时将隔离存储卷绑定到工作负载StatefulSet中。

    展开查看所需的YAML文件

    # 创建CNFS、StorageClass和StatefulSet对象。
    cat << EOF | kubectl apply -f -
    apiVersion: storage.alibabacloud.com/v1beta1
    kind: ContainerNetworkFileSystem
    metadata:
      name: cnfs-efc-cpfs
    spec:
      type: cpfs
      reclaimPolicy: Retain
      parameters:
        protocolServer: cpfs-xxxx.xxxx.cpfs.aliyuncs.com # 填写CPFS的协议服务的挂载点域名。
        useClient: EFCClient  # 使用EFC客户端进行挂载。
    ---
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: cnfs-efc-cpfs-sc
    mountOptions:
      - nolock,tcp,noresvport
      - vers=3
    parameters:
      volumeAs: subpath
      containerNetworkFileSystem: "cnfs-efc-cpfs" # 引用创建的CNFS对象cnfs-efc-cpfs。
      path: "/share"
    provisioner: nasplugin.csi.alibabacloud.com
    reclaimPolicy: Delete
    allowVolumeExpansion: true
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: cnfs-efc-cpfs-sts
    spec:
      selector:
        matchLabels:
          app: busybox
      serviceName: "busybox"
      replicas: 2
      template:
        metadata:
          labels:
            app: busybox
        spec:
          containers:
          - name: busybox
            image: busybox
            command: ["/bin/sh"]
            args: ["-c", "sleep 3600;"]
            volumeMounts:
            - name: pvc
              mountPath: /data
      volumeClaimTemplates:
      - metadata:
          name: pvc
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "cnfs-efc-cpfs-sc"
          resources:
            requests:
              storage: 50Gi
    EOF
  2. 执行以下命令,查看CNFS是否为可用状态。

    kubectl get cnfs cnfs-efc-cpfs -oyaml | grep status

    预期输出:

    status:
        status: Ready
      status: Available

    预期输出表明,CNFS状态为Available可用状态。

  3. 执行以下命令,查看PVC是否为绑定状态。

    kubectl get pvc -owide | grep cnfs-efc-cpfs-sc

    预期输出:

    pvc-cnfs-efc-cpfs-sts-0   Bound    nas-38727f0c-58c7-40df-b2e2-80537fcd74ae   50Gi       RWO            cnfs-efc-cpfs-sc   66s     Filesystem
    pvc-cnfs-efc-cpfs-sts-1   Bound    nas-ead04f09-ca37-408c-a50d-17e609fd48cf   50Gi       RWO            cnfs-efc-cpfs-sc   4m50s   Filesystem

    预期输出表明,PVC状态为Bound绑定状态。

  4. 执行以下命令,查看Pod是否为运行状态。

    kubectl get sts cnfs-efc-cpfs-sts -owide

    预期输出:

    NAME                READY   AGE   CONTAINERS   IMAGES
    cnfs-efc-cpfs-sts   2/2     198s   busybox      busybox
  5. 执行以下命令,查看其中一个Pod是否挂载成功。

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

    预期输出:

    bindroot-90f07-x6ducKqW:cpfs-03129888b1d5c6e7-031b038b4345e7cen.cn-beijing.cpfs.aliyuncs.com:/share/nas-e502f35f-2d42-4292-bf2c-c39885c38820 on /data type alifuse.aliyun-alinas-efc (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other)

    预期输出表明,CNFS使用EFC客户端已成功挂载CPFS文件系统。

步骤三:查看持久化数据是否写入成功

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

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

    预期输出:

    total 1G
    drwxr-xr-x    2 root     root        4.0K Apr 19 12:42 .
    drwxr-xr-x    1 root     root        4.0K Apr 19 12:42 ..
    -rw-r--r--    1 root     root        1.0G Apr 19 12:50 1G.tmpfile
    1+0 records in
    1+0 records out
    1073741824 bytes (1.0GB) copied, 2.729605 seconds, 375.1MB/s
  2. 执行以下命令,在名称为cnfs-xxx-cpfs-sts-1的Pod中,确认并不存在该临时文件。

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

    预期输出:

    total 5K
    drwxr-xr-x    2 root     root        4.0K Apr 19 12:42 .
    drwxr-xr-x    1 root     root        4.0K Apr 19 12:42 ..

    预期输出表明,名称为cnfs-xxx-cpfs-sts-0的Pod与名称为cnfs-xxx-cpfs-sts-1的Pod中,所使用的存储卷相互隔离。