# 对象存储卷挂载设置自定义访问密钥（AK/SK）
[CCE容器存储（Everest）](https://support.huaweicloud.com/usermanual-cce/cce_10_0066.html)提供了设置自定义访问密钥的能力，这样可以让IAM用户使用自己的访问密钥挂载对象存储卷，可以基于IAM权限对子用户访问OBS的权限进行控制（具体请参见[OBS不同权限控制方式的区别](https://support.huaweicloud.com/perms-cfg-obs/obs_40_0001.html)）。
#### 前提条件
- [CCE容器存储（Everest）](https://support.huaweicloud.com/usermanual-cce/cce_10_0066.html)要求1.2.8及以上版本。
- 集群要求1.15.11及以上版本。
 
#### 约束与限制
- 对象存储卷使用自定义访问密钥（AK/SK）时，对应的AK/SK不允许删除或禁用，否则业务容器将无法访问已挂载的对象存储。
- 自定义访问密钥暂不支持安全容器。
 
#### 禁用全局访问密钥
在老版本控制台创建对象存储卷时会要求您上传AK/SK，该AK/SK为全局访问密钥，对象存储卷挂载时默认使用该密钥，相当于所有IAM用户（即子用户）都使用同一个访问密钥挂载对象桶，对桶的权限都是一样的，导致无法对IAM用户使用对象存储桶进行权限控制。
如果您之前上传过AK/SK（即集群中kube-system命名空间下存在名为paas.longaksk的密钥），为防止IAM用户越权，建议禁用全局访问密钥，这样使用对象存储时就不会自动使用在控制台上传的全局访问密钥。**如果没有上传过AK/SK，可以忽略此部分内容。**
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
- 禁用全局访问密钥时要求当前集群中无对象存储卷，否则挂载了该对象卷的工作负载扩容或重启的时候会由于必须指定访问密钥而导致挂卷失败。
- 禁用全局访问密钥后，创建PV和PVC时必须指定挂载访问密钥，否则会导致对象卷挂载失败。
 
禁用全局访问密钥的方式如下：
- 在Everest插件中关闭自动挂载访问密钥，即将**disable_auto_mount_secret** 参数设置为true。
  步骤如下：
  以下步骤适用于2.x版本（2.1.42及以上）的插件：
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。
  
  2. 单击左侧导航栏的"插件中心"，在右侧找到**CCE容器存储（Everest）**插件，单击"编辑"。
  
  3. 设置插件支持的"参数配置"。修改"禁用全局访问密钥挂载对象存储（disable_auto_mount_secret）"为是。
  
  4. 单击"确定"。
   
  以下步骤适用于1.x版本的插件（该方式在升级插件时无法保留已修改的配置，建议使用2.x版本的插件）：
  1. 使用kubectl连接集群，执行以下命令修改插件配置。
     ```
     kubectl edit ds everest-csi-driver -nkube-system
     ```
     
  
  2. 搜索disable-auto-mount-secret，并将值设置为true。 ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002538489411.png "点击放大")
     
  
  3. 执行**:wq**保存退出，等待实例重启完毕即可。
    
- 在[配置中心 \> 集群配置](https://support.huaweicloud.com/usermanual-cce/cce_10_0782.html#cce_10_0782__section138274223718)中关闭集群的全局访问密钥，关闭后将直接删除集群中kube-system命名空间下的全局访问密钥（名为paas.longaksk）。
 
 #### 获取访问密钥
1. 打开["我的凭证"页面](https://console.huaweicloud.com/iam/#/mine/apiCredential)。
2. 在左侧导航栏单击"访问密钥"。
3. 单击"新增访问密钥"，进入"新增访问密钥"页面。
4. 单击"确定"，下载访问密钥。
 
#### 使用访问密钥创建Secret
1. 获取访问密钥。
2. 对访问密钥进行base64编码（假设上文获取到的AK为"xxx"，SK为"yyy"）。 
   ```
   echo -n xxx|base64
   echo -n yyy|base64
   ```
   记录编码后的AK和SK。
   
   
3. 新建一个Secret的YAML，如test-user.yaml。 
   ```
   apiVersion: v1
   data:
     access.key: WE5WWVhVNU*****
     secret.key: Nnk4emJyZ0*****
   kind: Secret
   metadata:
     name: test-user
     namespace: default
     labels:
       secret.kubernetes.io/used-by: csi
   type: cfe/secure-opaque
   ```
   其中：
   
   | 参数                                  | 描述                                                                           |
   |:---|:---|
   | access.key                       | base64编码后的AK。                                                             |
   | secret.key                        | base64编码后的SK。                                                                |
   | name                             | Secret的名称。                                                                    |
   | namespace                        | Secret的命名空间。                                                                  |
   | secret.kubernetes.io/used-by: csi | 带上这个标签才能在控制台上创建OBS PV/PVC时可见。                                                 |
   | type                             | 密钥类型，该值必须为cfe/secure-opaque。 使用该类型，用户输入的数据会自动加密。 |
      
   
   
4. 创建Secret。 
   ```
   kubectl create -f test-user.yaml
   ```
   
   
 
#### 在对象存储卷中挂载Secret
创建对象存储卷的方法不同，其挂载方式也不同，具体如下：
- [静态创建对象存储卷]
  使用访问密钥创建Secret后，在创建PV时只需要关联上Secret，就可以使用Secret中的访问密钥（AK/SK）挂载对象存储卷。
  1. 登录[OBS控制台](https://console.huaweicloud.com/obs/#/obs/manager/buckets)，创建对象存储桶，记录桶名称和存储类型，以并行文件系统为例。
  
  2. 新建一个PV的YAML文件，如pv-example.yaml。 
     ```
     apiVersion: v1
     kind: PersistentVolume
     metadata:
       name: pv-obs-example
       annotations:
         pv.kubernetes.io/provisioned-by: everest-csi-provisioner
     spec:
       accessModes:
       - ReadWriteMany
       capacity:
         storage: 1Gi
       csi:
         nodePublishSecretRef:
           name: test-user
           namespace: default
         driver: obs.csi.everest.io
         fsType: obsfs
         volumeAttributes:
           everest.io/obs-volume-type: STANDARD
           everest.io/region: cn-north-4
           storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner
         volumeHandle: obs-normal-static-pv
       persistentVolumeReclaimPolicy: Delete
       storageClassName: csi-obs
     ```
     
     | 参数                    | 描述                                                                                                                                                                                                                     |
     |:---|:---|
     | nodePublishSecretRef | 挂载时指定的密钥，其中： - name：指定Secret的名字。  - namespace：指定Secret的命名空间。   |
     | fsType                  | 文件类型，支持"obsfs"与"s3fs"，取值为s3fs时创建是OBS对象桶；取值为obsfs时创建的是OBS并行文件系统。                                                                                                                                                        |
     | volumeHandle         | 对象存储的名称。                                                                                                                                                                                                             |
        
     
     
  
  3. 创建PV。 
     ```
     kubectl create -f pv-example.yaml
     ```
     PV创建完成后，就可以创建PVC关联PV。
     
     
  
  4. 新建一个PVC的YAML文件，如pvc-example.yaml。 
     **PVC YAML文件配置示例：**
     ```
     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       annotations:
         csi.storage.k8s.io/node-publish-secret-name: test-user
         csi.storage.k8s.io/node-publish-secret-namespace: default
         volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner
         everest.io/obs-volume-type: STANDARD
         csi.storage.k8s.io/fstype: obsfs
       name: obs-secret
       namespace: default
     spec:
       accessModes:
       - ReadWriteMany
       resources:
         requests:
           storage: 1Gi
       storageClassName: csi-obs
       volumeName: pv-obs-example
     ```
     
     | 参数                                                | 描述               |
     |:---|:---|
     | csi.storage.k8s.io/node-publish-secret-name      | 指定Secret的名字。    |
     | csi.storage.k8s.io/node-publish-secret-namespace | 指定Secret的命名空间。 |
        
     
     
  
  5. 创建PVC。 
     ```
     kubectl create -f pvc-example.yaml
     ```
     PVC创建后，就可以创建工作负载挂载PVC使用存储。
     
     
   
- [动态创建对象存储卷]
  动态创建对象存储卷时，可通过如下方法指定挂载密钥。
  1. 新建一个PVC的YAML文件，如pvc-example.yaml。 
     ```
     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       annotations:
         csi.storage.k8s.io/node-publish-secret-name: test-user
         csi.storage.k8s.io/node-publish-secret-namespace: default
         everest.io/obs-volume-type: STANDARD
         csi.storage.k8s.io/fstype: obsfs
       name: obs-secret
       namespace: default
     spec:
       accessModes:
       - ReadWriteMany
       resources:
         requests:
           storage: 1Gi
       storageClassName: csi-obs
     ```
     
     | 参数                                                 | 描述                 |
     |:---|:---|
     | csi.storage.k8s.io/node-publish-secret-name        | 指定Secret的名字。    |
     | csi.storage.k8s.io/node-publish-secret-namespace | 指定Secret的命名空间。 |
        
     
     
  
  2. 创建PVC。 
     ```
     kubectl create -f pvc-example.yaml
     ```
     PVC创建后，就可以创建工作负载挂载PVC使用存储。
     
     
   
#### 配置验证
根据上述步骤，使用IAM用户的密钥挂载对象存储卷。假设工作负载名称为obs-secret，容器内挂载目录是/temp，IAM用户权限为CCE ReadOnlyAccess和Tenant Guest。
1. 查询工作负载实例名称。
   ```
   kubectl get pod | grep obs-secret
   ```
   期望输出：
   ```
   obs-secret-5cd558f76f-vxslv          1/1     Running   0          3m22s
   ```
   
2. 查询挂载目录下对象，查询正常。
   ```
   kubectl exec obs-secret-5cd558f76f-vxslv -- ls -l /temp/
   ```
   
3. 尝试在挂载目录内写入数据，写入失败。
   ```
   kubectl exec obs-secret-5cd558f76f-vxslv -- touch /temp/test
   ```
   期望输出：
   ```
   touch: setting times of '/temp/test': No such file or directory
   command terminated with exit code 1
   ```
   
4. 参考桶策略配置，给挂载桶的子用户设置读写权限。 ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000001244141105.png "点击放大")
   
   
5. 再次尝试在挂载目录内写入数据，写入成功。
   ```
   kubectl exec obs-secret-5cd558f76f-vxslv -- touch /temp/test
   ```
   
6. 查看容器内挂载目录，验证数据写入成功。
   ```
   kubectl exec obs-secret-5cd558f76f-vxslv -- ls -l /temp/
   ```
   期望输出：
   ```
   -rwxrwxrwx 1 root root 0 Jun  7 01:52 test
   ```
   
 
