# 对象存储卷挂载设置自定义临时访问密钥（临时AK/SK）
在容器化应用部署与管理中，用户经常需要将对象存储桶挂载到容器中使用。然而，在这一过程中，用户必须配置永久的访问密钥（AK/SK），这增加了较大的安全风险，与当前越来越多的企业追求的最小权限原则相悖。特别是对于注重安全性的企业而言，永久AK/SK一旦泄露，将对数据安全构成严重威胁。为此，[CCE容器存储插件（Everest）](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0066.html)支持使用自定义临时访问密钥（临时AK/SK）挂载对象存储卷，无需使用永久AK/SK，即可安全地访问OBS桶，满足企业对数据安全的高标准要求。与IAM用户的永久访问密钥相比，临时访问密钥的有效时间为15min至24h，降低了密钥泄露带来的安全风险。
#### 前提条件
- Autopilot集群版本满足以下要求：
  - v1.28集群：v1.28.10-r0及以上版本
  
  - v1.31集群：v1.31.10-r0及以上版本
  
  - v1.32集群：v1.32.6-r0及以上版本
  
  - 其他更高版本的集群
   
 
#### 约束与限制
- 对象存储卷使用自定义临时访问密钥（临时AK/SK）时，您**需要定时更新临时AK/SK来** **确保不过期**，否则业务容器将无法访问已挂载的对象存储。
- 获取的临时访问密钥具有与IAM用户相同的权限，该IAM用户要求有读写OBS的权限。
  基本权限范围示例如下，您也可以根据需求自定义授权：
  - obs:bucket:PutLifecycleConfiguration
    
  
  - obs:bucket:ListBucketMultipartUploads
    
  
  - obs:object:DeleteAccessLabel
    
  
  - obs:object:PutAccessLabel
    
  
  - obs:object:GetObjectVersion
    
  
  - obs:object:PutObjectVersionTagging
    
  
  - obs:object:GetObject
    
  
  - obs:object:ModifyObjectMetaData
  
  - obs:bucket:DeleteModerationPolicy
  
  - obs:object:GetObjectTagging
  
  - obs:object:DeleteObject
  
  - obs:object:ListMultipartUploadParts
  
  - obs:bucket:HeadBucket
  
  - obs:object:AbortMultipartUpload
  
  - obs:object:DeleteObjectVersion
  
  - obs:bucket:ListBucketVersions
  
  - obs:bucket:ListBucket
  
  - obs:object:PutObject
    
 
#### 使用访问密钥创建Secret
1. 获取临时访问密钥（AK、SK、STS Token），详情请参见[临时访问密钥（企业联邦用户）](https://support.huaweicloud.com/usermanual-ca/ca_01_0005.html)。
2. 对访问密钥进行base64编码（假设上文获取到的AK为"xxx"，SK为"yyy"，STS Token为 "zzz"）。 
   ```
   echo -n xxx|base64
   echo -n yyy|base64
   echo -n zzz|base64 -w 0
   ```
   记录编码后的AK、SK和STS Token。
   
   
3. 新建一个Secret的YAML，如test-user.yaml。 
   ```
   apiVersion: v1
   data:
     access.key: WE5WWVhVNU*****
     secret.key: Nnk4emJyZ0*****
     security.token: Adfaf*****
   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。                                                                                            |
   | security.token                    | base64编码后的STS Token。                                                                                     |
   | 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对象桶，配套使用s3fs挂载；取值为obsfs时创建的是obs并行文件系统，配套使用obsfs挂载。                                                                                                                                                                                                                                                                                                                                          |
     | 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 po \| 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-autopilot/zh-cn_image_0000001898717029.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
   ```
   
 
