阿里云 Kubernetes CSI 支持 2 种类型的 NAS 动态存储卷挂载:subpath 方式和 filesystem 方式。

前提条件

使用此方案,需要在集群中部署 CSI 驱动(Kubernetes 集群默认已部署该驱动)。

如果您没有部署 csi-nas-plugin。请参见安装插件。

subpath 类型的 NAS 动态存储卷

当您的多个 Kubernetes 应用或者 Pod 需要挂载相同的 NAS 存储卷共享数据时,或不同的 Pod 挂载相同 NAS 文件系统的不同子目录时, 可以使用
subpath 类型的 NAS 动态存储卷方式。

NAS 动态存储卷的挂载方式为 subpath 类型时,您需要手动创建 NAS 文件系统和挂载点。

  1. 创建 NAS 文件系统和挂载点。
    1. 登录NAS控制台。
    2. 创建 NAS 文件系统。请参见管理文件系统。
      创建文件系统
    3. 添加挂载点。请参见管理挂载点。
      添加挂载点
  2. 创建 StorageClass。
    1. 创建并拷贝以下内容到alicloud-nas-subpath.yaml文件中。
      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: alicloud-nas-subpath
      mountOptions:
      - nolock,tcp,noresvport
      - vers=3
      parameters:
        volumeAs: subpath
        server: "xxxxxxx.cn-hangzhou.nas.aliyuncs.com:/k8s/"
      provisioner: nasplugin.csi.alibabacloud.com
      reclaimPolicy: Retain

    2. 执行以下命令创建 StorageClass。
      kubectl create -f alicloud-nas-subpath.yaml

  3. 创建 PV/PVC 和 Pod 挂载 NAS 存储卷。
    创建 Pod nginx-1nginx-2共享 NAS 存储卷的同一个子目录,pvc.yamlnginx-1.yamlnginx-2.yaml文件内容如下。

    pvc.yaml

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: nas-csi-pvc
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: alicloud-nas-subpath
      resources:
        requests:
          storage: 20Gi

    nginx-1.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deployment-nas-1
      labels:
        app: nginx-1
    spec:
      selector:
        matchLabels:
          app: nginx-1
      template:
        metadata:
          labels:
            app: nginx-1
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
            volumeMounts:
              - name: nas-pvc
                mountPath: "/data"
          volumes:
            - name: nas-pvc
              persistentVolumeClaim:
                claimName: nas-csi-pvc

    nginx-2.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deployment-nas-2
      labels:
        app: nginx-2
    spec:
      selector:
        matchLabels:
          app: nginx-2
      template:
        metadata:
          labels:
            app: nginx-2
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
            volumeMounts:
              - name: nas-pvc
                mountPath: "/data"
          volumes:
            - name: nas-pvc
              persistentVolumeClaim:
                claimName: nas-csi-pvc

    执行如下命令,创建 PVC 和 Deployment。

    $ kubectl create -f pvc.yaml -f nginx-1.yaml -f nginx-2.yaml
    
    $ kubectl get po
    NAME                                READY   STATUS    RESTARTS   AGE
    deployment-nas-1-5b5cdb85f6-nhklx   1/1     Running   0          32s
    deployment-nas-2-c5bb4746c-4jw5l    1/1     Running   0          32s

    说明 NAS 存储卷的xxxxxxx.cn-hangzhou.nas.aliyuncs.com:/share/nas-79438493-f3e0-11e9-bbe5-00163e09c2be 会同时挂载到 deployment-nas-1-5b5cdb85f6-nhklxdeployment-nas-2-c5bb4746c-4jw5l/data目录下。其中:

    • /share:StorageClass 中指定的 subpath。
    • nas-79438493-f3e0-11e9-bbe5-00163e09c2be:pv 的名称。

    如果您需要为不同的 Pod 挂载同一个 NAS 文件系统的不同子目录, 则需要分别创建 pvc-1 和 nginx-1 以及 pvc-2 和 nginx-2。

filesystem 类型的 NAS 动态存储卷

注意 filesystem 类型的 NAS 动态卷在删除时默认保留文件系统和挂载点, 若需要在释放 pv 资源的同时释放 NAS 文件系统和挂载点, 则需要同时设置 StorageClass
中的 reclaimPolicy 为 Delete 且 deleteVolume 的值为 true

当您的 Kubernetes 应用需要动态创建和删除 NAS 文件系统和挂载点时, 可以使用 filesystem 类型。

使用 filesystem 类型 NAS 存储卷的 Pod 只能创建一个文件系统和一个挂载点, 多个 Pod 之间无法共享一个存储卷。

  1. RAM Policy 设置和授予。
    filesystem 类型的 NAS 存储卷涉及 NAS 文件系统和挂载点的动态创建与删除, 需要授予 csi-nasprovisioner 相应的权限,RAM Policy
    的最小集合如下:

    {
        "Action": [
            "nas:DescribeMountTargets",
            "nas:CreateMountTarget",
            "nas:DeleteFileSystem",
            "nas:DeleteMountTarget",
            "nas:CreateFileSystem"
        ],
        "Resource": [
            "*"
        ],
            "Effect": "Allow"
    }

    您可以通过以下任意一种方式进行授权:

    • 编辑 Kubernetes 集群的 Master RAM 角色中的自定义策略内容,添加以上 NAS 相关的权限设置。请参见角色授权。自定义授权
    • 创建子账号授权以上 RAM Policy 并生成 AccessKey,配置到 StatefulSet csi-provisioner 中 csi-nasprovisioner
      的 env 变量中。请参见角色授权。

      env:
          - name: CSI_ENDPOINT
              value: unix://socketDir/csi.sock
          - name: ACCESS_KEY_ID
              value: ""
          - name: ACCESS_KEY_SECRET
              value: ""
  2. 创建 StorageClass。
    1. 创建并拷贝以下内容到alicloud-nas-fs.yaml文件中。
      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: alicloud-nas-fs
      mountOptions:
      - nolock,tcp,noresvport
      - vers=3
      parameters:
        volumeAs: filesystem
        vpcId: "vpc-xxxxxxxxxxxx"
        vSwitchId: "vsw-xxxxxxxxx"
        deleteVolume: "false"
      provisioner: nasplugin.csi.alibabacloud.com
      reclaimPolicy: Retain

    2. 执行以下命令创建 StorageClass。
      kubectl create -f alicloud-nas-fs.yaml

  3. 创建 PV/PVC 和 Pod 挂载 NAS 存储卷。
    pvc.yamlnginx.yaml 文件内容如下:

    pvc.yaml

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: nas-csi-pvc-fs
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: alicloud-nas-fs
      resources:
        requests:
          storage: 20Gi

    nginx.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deployment-nas-fs
      labels:
        app: nginx
    spec:
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
            volumeMounts:
              - name: nas-pvc
                mountPath: "/data"
          volumes:
            - name: nas-pvc
              persistentVolumeClaim:
                claimName: nas-csi-pvc-fs

    执行以下命令,创建 PVC 和 Deployment。

    kubectl create -f pvc.yaml -f nginx.yaml

这种场景下,CSI 会在 PVC 创建时动态新建 NAS 文件系统和挂载点, PVC 删除时动态删除挂载点和文件系统。