
# 通过动态存储卷创建SFS子目录
通常情况下，在工作负载容器中挂载SFS类型的存储卷时，默认会将根目录挂载到容器中。为了更加经济合理地利用存储容量，CCE支持在创建PVC时动态创建SFS子目录，实现不同工作负载共享使用SFS。
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/notice_3.0-zh-cn.png)
仅通用文件系统（原SFS 3.0 容量型）支持动态创建子目录。
#### 前提条件
- 您已经创建好一个集群，并且在该集群中安装2.4.41及以上版本的[CCE容器存储（Everest）](https://support.huaweicloud.com/usermanual-cce/cce_10_0066.html)。
- 如果您需要通过命令行创建，需要使用kubectl连接到集群，详情请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)。
- 您已经创建好一个状态可用的SFS，并且SFS与集群在同一个VPC内。使用通用文件系统（原SFS 3.0 容量型）时，您需要提前在集群所在VPC创建一个VPC终端节点，集群需要通过VPC终端节点访问通用文件系统。配置VPC终端节点的方法请参见[配置VPC终端节点](https://support.huaweicloud.com/usermanual-sfs/sfs_01_0134.html)。
 
#### 动态创建SFS子目录
在CCE中，基于已配置的StorageClass，用户可通过控制台或kubectl命令行方式创建SFS子目录的PVC，系统将自动分配存储资源并挂载至工作负载。具体步骤如下：
- [控制台方式]
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。
  
  2. 在左侧导航栏选择"存储"，在右侧选择"存储卷声明"页签。单击右上角"创建存储卷声明 PVC"，在弹出的窗口中填写存储卷声明参数。 
     
     | 参数      | 描述                                                                                                                                                                                                                                                                                                                                                   |
     |:---|:---|
     | 存储卷声明类型 | 本文中选择"文件存储"。                                                                                                                                                                                                                                                                                                                                         |
     | PVC名称   | 输入PVC的名称，同一命名空间下的PVC名称需唯一。                                                                                                                                                                                                                                                                                                                           |
     | 创建方式    | 选择"动态创建子目录"。                                                                                                                                                                                                                                                                                                                                         |
     | 存储类     | 选择文件存储对应的存储类为csi-sfs。 您可以自建存储类并配置回收策略和绑定模式，具体操作请参见[StorageClass基础配置](https://support.huaweicloud.com/usermanual-cce/cce_10_0380.html#cce_10_0380__section1074117311660)。                                                                                                                                                |
     | 访问模式    | 文件存储类型的存储卷仅支持ReadWriteMany，表示存储卷可以被多个节点以读写方式挂载，详情请参见[存储卷访问模式](https://support.huaweicloud.com/usermanual-cce/cce_10_0378.html#cce_10_0378__section43881411172418)。                                                                                                                                                                                   |
     | 文件存储    | 单击"选择文件存储"，您可以在新页面中勾选满足要求的文件存储，并单击"确定"。                                                                                                                                                                                                                                                                                                              |
     | 子目录     | 请填写子目录绝对路径，例如/a/b。                                                                                                                                                                                                                                                                                                                                   |
     | 子目录回收策略 | 删除PVC时是否保留子目录。 - 保留：删除PVC，PV会被删除，但**PV关联的子目录会被保留**。  - 删除：删除PVC，**PV及其关联的子目录均会被删除** 。 说明： 删除子目录时，仅删除PVC参数中设置的子目录绝对路径，不会级联删除上层目录。    |
        
     
     
  
  3. 单击"创建"，将同时为您创建存储卷声明和存储卷。 
     您可以在左侧导航栏中选择"存储"，在"存储卷声明"和"存储卷"页签下查看已经创建的存储卷声明和存储卷。
     
     
   
- [kubectl命令行方式]
  1. 使用kubectl连接集群。
  
  2. 创建pvc-sfs-subpath.yaml文件。 
     ```
     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       name: pvc-sfs-subpath    # PVC的名称
       namespace: default
       annotations:
         everest.io/csi.volume-as: absolute-path                # 表示使用SFS子目录
         everest.io/csi.sfs30-name: <sfs_name>                    # SFS实例的名称
         everest.io/csi.path: /a                                # 自动创建的子目录，必须为绝对路径
         everest.io/csi.reclaim-policy: retain-volume-only      # 表示删除PVC时，PV会被删除，但PV关联的子目录会被保留
     spec:
       accessModes:
         - ReadWriteMany      # SFS必须为ReadWriteMany
       resources:
         requests:
           storage: 1Gi      # 对于SFS子目录类型的PVC，此处无实际意义，仅作校验需要（不能为空和0）
       storageClassName: csi-sfs     # 通用文件系统（原SFS 3.0 容量型）存储类名称
     ```
     表1关键参数说明 
     | 参数                            | 是否必选 | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
     |:---|:---|:---|
     | everest.io/csi.volume-as      | 是    | 使用动态创建SFS子目录时，固定取值为"absolute-path"。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
     | everest.io/csi.sfs30-name     | 是    | SFS实例的名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
     | everest.io/csi.path           | 是    | 自动创建的子目录，必须为绝对路径。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
     | everest.io/csi.reclaim-policy | 是    | 删除PVC时是否保留子目录，该参数需与[PV回收策略](https://support.huaweicloud.com/usermanual-cce/cce_10_0378.html#cce_10_0378__section19999142414413)配合使用。仅当PV回收策略为"Delete"时生效，取值如下： - retain-volume-only：表示删除PVC时，PV会被删除，但**PV关联的子目录会被保留**。  - delete：表示删除PVC，**PV及其关联的子目录均会被删除** 。 说明： 删除子目录时，仅删除PVC参数中设置的子目录绝对路径，不会级联删除上层目录。    |
     | storage                       | 是    | PVC申请容量，单位为Gi。 对SFS子目录类型的PVC来说，此处仅为校验需要（不能为空和0），设置的大小不起作用，此处可以设定为固定值1Gi。                                                                                                                                                                                                                                                                                                                                                                                                                            |
        
     
     
  
  3. 执行以下命令，创建PVC。 
     ```
     kubectl apply -f pvc-sfs-subpath.yaml
     ```
     验证PVC创建成功：
     ```
     kubectl get pvc pvc-sfs-subpath
     ```
     回显示例如下：
     ```
     NAME                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
     pvc-sfs-subpath     Bound    pvc-xxxx-xxxx-xxxx-xxxx                    1Gi        RWX            csi-sfs        10s
     ```
     其中STATUS必须为Bound，表示PVC已成功绑定到PV。
     
     
   
#### 验证子目录挂载和读写
PVC创建后，可将其绑定的PV挂载到应用中。本小节将创建两个Deployment，引用同一个PVC，实现多个Pod共享同一NAS子目录。
1. 创建工作负载YAML文件。 
   创建deployment-sfs-demo.yaml文件，内容如下：
   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: sfs-demo
     namespace: default
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: sfs-demo
     template:
       metadata:
         labels:
           app: sfs-demo
       spec:
         containers:
         - name: container-0
           image: nginx:latest
           imagePullPolicy: IfNotPresent
           volumeMounts:
           - name: sfs-storage
             mountPath: /usr/share/nginx/html/data   # 容器内挂载路径
         volumes:
         - name: sfs-storage
           persistentVolumeClaim:
             claimName: pvc-sfs-subpath   # 引用上一步创建的PVC
         imagePullSecrets:
         - name: default-secret
   ```
   
   
2. 创建工作负载。 
   ```
   kubectl apply -f deployment-sfs-demo.yaml
   ```
   
   
3. 确认子目录已正确挂载。 
   ```
   # 获取Pod名称
   POD_NAME=$(kubectl get pods -l app=sfs-demo -o jsonpath='{.items[0].metadata.name}')
   # 进入容器并检查挂载点
   kubectl exec -it $POD_NAME -- /bin/sh -c "ls -ld /usr/share/nginx/html/data"
   ```
   预期输出：
   ```
   drwxr-xr-x 2 root root 0 ... /usr/share/nginx/html/data
   ```
   目录存在，且权限正常。
   
   
4. 测试文件读写功能。 
   ```
   # 在容器内写入测试文件
   kubectl exec -it $POD_NAME -- /bin/sh -c "echo 'Hello SFS Subpath - End to End Test' > /usr/share/nginx/html/data/test.txt"
   # 读取测试文件验证写入成功
   kubectl exec -it $POD_NAME -- /bin/sh -c "cat /usr/share/nginx/html/data/test.txt"
   ```
   预期输出：
   ```
   Hello SFS Subpath - End to End Test
   ```
   能够成功写入并读取文件，证明存储卷读写功能正常。
   
   
 
#### 相关文档
如果工作负载挂载存储卷时出现无法挂载或挂载超时的情况，请参见[工作负载异常：存储卷无法挂载或挂载超时](https://support.huaweicloud.com/cce_faq/cce_faq_00200.html)排查解决。
