文档首页/ 云容器引擎 CCE/ 最佳实践/ 存储/ 跨账号挂载对象存储
更新时间:2024-11-12 GMT+08:00

跨账号挂载对象存储

应用场景

  • 跨账号数据共享。例如,公司内部多团队需要共享数据,但不同团队使用不同的账号。
  • 跨账户数据迁移和备份。例如,账号A即将停用,所有的数据需要迁移至账户B。
  • 数据处理与分析。例如,账号B是外部数据处理商,需要访问账户A的原始数据进行大数据分析和机器学习等操作。

通过跨账户挂载对象存储,您可以实现数据共享,降低存储和传输成本,同时确保数据的安全性和一致性。这种方式使多个团队或组织能够安全、便捷地访问彼此的数据资源,避免重复存储和冗余传输,同时确保数据的最新性和合规性,从而提升整体的业务效率和安全性。

操作流程

假设账号B在某种情况下需要访问和使用账号A的某个OBS桶,具体操作流程请参见图1表1

图1 跨账号挂载对象存储
表1 操作流程说明

操作流程

说明

步骤一:创建OBS桶策略和桶ACL

账户A对OBS配置桶策略和和桶ACL,授予账号B相应的权限(如读写权限)。

步骤二:创建挂载OBS的工作负载

基于账号A的OBS桶,账号B创建对应的PV和PVC,并将PVC挂载到需要的工作负载中。

步骤三:检查Pod对OBS桶的操作权限

基于桶策略,检查账号B创建的Pod实例是否具有相应权限。

步骤四:清理资源

完成该示例的学习后,您可以清理相关资源以避免产生结算费用。

前提条件

  • 涉及账户在同一区域内。
  • 已创建一个安装CCE容器存储(Everest)的集群,其中要求Everest版本≥1.1.11,集群版本≥1.15。若没有可用集群 ,请参照购买Standard/Turbo集群创建。
  • 集群所在VPC下,已创建绑定弹性公网IP的ECS虚拟机,且该ECS通过kubectl连接集群。若没有连接集群,请参照通过kubectl连接集群

步骤一:创建OBS桶策略和桶ACL

账户A对OBS配置桶策略和桶ACL,授予账号B相应的权限(如读写权限)。

  1. 登录OBS管理控制台,左侧导航栏选择“对象存储”
  2. 单击待操作桶,进入“对象”页面。
  3. 在左侧导航栏,单击“权限控制 > 桶策略”,单击“创建”,进入“创建桶策略”页面。
  4. 配置相关参数。本示例仅解释必要参数,其余保留默认值。关于配置参数的详细说明请参见桶策略

    表2 桶策略参数配置

    参数

    参数说明

    示例

    策略名称

    自定义名称。

    example01

    效力

    用于指定策略的行为。

    • 允许:表示允许策略中定义的操作。
    • 拒绝:表示拒绝策略中定义的操作。

    允许

    被授权用户

    用于指定被授权账户(可多选)。对于不同类型的授权账户,OBS控制台在授权操作中预置了不同的模板配置,具体请参见使用模板创建桶策略

    • 所有账户:任何账户不通过身份认证即可执行当前桶策略,数据可能存在安全风险。
    • 当前账户:授权当前账户下的特定IAM账户。
    • 其他账户:授权其他账户下的特定IAM账户。

    其他账户

    XXX(账户ID)/XXX(IAM ID)

    授权资源

    用于指定授权的资源范围。

    • 整个桶(包括桶内对象):允许被授权账户对整个桶和桶内的所有对象进行操作。
    • 当前桶:仅允许被授权账户对整个桶进行操作。
    • 指定对象:仅允许被授权账户对桶内特定对象进行操作。

    整个桶(包括桶内对象)

    授权操作

    用于指定授权的具体操作。

    • 模板配置:OBS控制台预置的权限配置模板。当选择“桶读写”时,高级设置默认“排除以上授权操作”
    • 自定义配置:自定义选择授权的具体操作。

    模板配置 > 桶读写

    图2 创建桶策略

  5. 在左侧导航栏,单击“权限控制 > 桶ACL”,单击“用户权限 > 增加”,输入授权用户的账号ID,“桶访问权限”勾选“读取权限”和“写入权限”,“对象权限”勾选“对象读权限”“ACL访问权限”勾选“读取权限”和“写入权限”,单击“确定”。

步骤二:创建挂载OBS的工作负载

基于账号A的OBS,账号B创建对应的PV和PVC,并将PVC挂载到需要的工作负载中。

  1. 创建名为paas-obs-endpoint的ConfigMap,配置OBS所在区域和Endpoint。

    vim config.yaml

    具体内容如下,参数说明请参见表3

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: paas-obs-endpoint   # 名称必须为paas-obs-endpoint
      namespace: kube-system    # 必须在kube-system命名空间下
    data:
      obs-endpoint: |
        {"<region_name>": "<endpoint_address>"}

    利用config.yaml创建ConfigMap。

    kubectl create -f config.yaml
    表3 ConfigMap参数说明

    ConfigMap

    说明

    示例

    metadata.name

    ConfigMap名称,固定为paas-obs-endpoint,不可修改。

    paas-obs-endpoint

    metadata.namespace

    命名空间,固定为系统命名空间kube-system,不可修改。

    kube-system

    data.obs-endpoint

    区域名称和Endpoint以键值对形式对应,<region_name>和<endpoint_address>需替换为具体值,多个取值间使用逗号隔开。

    Region对应的值请参见地区和终端节点

    {"ap-southeast-1": "https://obs.ap-southeast-1.myhuaweicloud.com:443", "ap-southeast-3": "https://obs.ap-southeast-3.myhuaweicloud.com:443"}

  2. 创建名为test-user的Secret,名称可自定义,用于在CSI挂载卷时提供访问凭证。

    1. 获取访问密钥。返回控制台,鼠标指向界面右上角的登录用户名,在下拉列表中单击“我的凭证”。

      在左侧导航栏单击“访问密钥”,单击“新增访问密钥”,进入“新增访问密钥”页面。

      单击“确定”,下载访问密钥。

    2. 对访问密钥进行base64编码(假设上文获取到的AK为“xxx”,SK为“yyy”),并记录编码后的AK和SK。
      echo -n xxx|base64
      echo -n yyy|base64
    3. 新建一个secret的YAML文件,如test_user.yaml。
      vim test_user.yaml

      文件内容如下,参数说明请参见表4

      apiVersion: v1
      data:
        access.key: QUxPQUlJU******
        secret.key: aVMwZkduQ******
      kind: Secret
      metadata:
        name: test-user
        namespace: default
      type: cfe/secure-opaque

      利用test_user.yaml创建Secret。

      kubectl create -f test_user.yaml
      表4 Secret参数说明

      参数

      说明

      示例

      access.key

      base64编码后的AK。

      QUxPQUlJU******

      secret.key

      base64编码后的SK。

      aVMwZkduQ******

      type

      密钥类型,固定为cfe/secure-opaque,不可修改。

      使用该类型,用户输入的数据会自动加密。

      cfe/secure-opaque

  3. 创建名为testing_abc的PV,并挂载名为test_user的Secret。

    vim testing_abc.yaml

    文件内容如下,参数说明请参见表5

    kind: PersistentVolume
    apiVersion: v1
    metadata:
      name: testing-abc
      annotations:
        pv.kubernetes.io/bound-by-controller: 'yes'
        pv.kubernetes.io/provisioned-by: everest-csi-provisioner
    spec:
      capacity:
        storage: 1Gi
      mountOptions:
      - default_acl=bucket-owner-full-control      #新增的OBS挂载参数
      csi:
        driver: obs.csi.everest.io
        volumeHandle: obs-cce-test                 # 待挂载的OBS桶的名称
        fsType: s3fs                               # obsfs表示并行文件系统;s3fs表示对象桶
        volumeAttributes:
          everest.io/obs-volume-type: STANDARD     # 桶类型,使用对象桶时支持标准(STANDARD)和低频(WARM)两种桶。
          everest.io/region: <region_name>         # OBS桶所在区域,需替换为具体取值
          storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner
        nodePublishSecretRef:                      # 挂载OBS桶使用的AK/SK
          name: test-user
          namespace: default
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain        # PV回收策略
      storageClassName: csi-obs                    # csi-obs是自动创建的OBS存储类,可以根据情况,自定义创建
      volumeMode: Filesystem

    利用testing_abc.yaml创建PV。

    kubectl create -f testing_abc.yaml
    表5 PV参数说明

    参数

    说明

    示例

    mountOptions.default_acl

    指定桶及对象的访问控制策略。本示例中,账户A是桶的所有者,账号A和账号B都可能是上传者。

    • private:只有桶的所有者可以完全访问桶或对象。
    • public-read:桶的所有者对桶或对象有完全控制权,其他用户可以读取数据,但不能修改、删除或上传数据。
    • public-read-write:桶的所有者对桶或对象有完全控制权,其他用户可以对数据进行读写操作。
    • bucket-owner-read:上传者对自己上传的对象具有完全的控制权限,而桶的所有者对对象有读取权限,常用于跨账户共享的场景
    • bucket-owner-full-control:上传者拥有对自己上传对象的写入权限,默认情况下可能没有读取权限。桶的所有者对对象具有完全控制权限,常用于跨账户共享的场景

    bucket-owner-full-control

    说明:

    由于账户A设置的桶策略中授予账号B整个桶的读写权限,所以账号B对整个桶(包括自己上传的对象和账户A上传的对象)具有写入和读取权限。

    csi.nodePublishSecretRef

    指定需要挂载的密钥。

    • name:Secret的名字。
    • namespace:Secret的命令空间。

    test-user

    default

    csi.volumeHandle

    指定需要挂载的OBS桶名称。

    obs-cce-test(账户A授权的OBS名称)

    csi.fsType

    指定文件类型。

    • obsfs:创建obs并行文件系统。
    • s3fs:创建obs对象桶。

    s3fs

    须知:

    PV和PVC指定的文件类型需一致,否则PVC无法绑定对应的PV。

    accessModes

    指定存储卷的访问模式,OBS仅支持ReadWriteMany。

    • ReadWriteOnce:存储卷可以被一个节点以读写方式挂载。
    • ReadWriteMany:存储卷可以被多个节点以读写方式挂载。

    ReadWriteMany

    persistentVolumeReclaimPolicy

    指定PV的回收策略。

    • Delete:当PVC被删除时,PV对象与底层存储资源均会被删除。YAML文件中若添加annotations“everest.io/reclaim-policy: retain-volume-only”,则底层存储资源会保留。
    • Retain:当PVC对象被删除时,PV对象与底层存储资源均不会被删除,需要手动删除回收。PVC删除后PV资源状态为“已释放(Released)”,且不能直接再次被PVC绑定使用。

    Retain

    说明:

    多个PV使用同一个对象存储时建议使用Retain,避免级联删除底层卷。

  4. 创建名为pvc-test-abc的PVC,并绑定新建的PV,即testing_abc。

    vim pvc_test_abc.yaml
    文件内容如下:
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-test-abc
      namespace: default
      annotations:
        csi.storage.k8s.io/node-publish-secret-name: test-user      # 挂载Secret
        csi.storage.k8s.io/node-publish-secret-namespace: default   # Secret的命名空间
        everest.io/obs-volume-type: STANDARD       # 桶类型,使用对象桶时支持标准(STANDARD)和低频(WARM)两种桶。
        csi.storage.k8s.io/fstype: s3fs            # 文件类型,obsfs表示并行文件系统;s3fs表示对象桶
        volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner
    spec:
      accessModes:
      - ReadWriteMany             # 对象存储必须为ReadWriteMany
      resources:
        requests:
          storage: 1Gi            # PVC申请容量大小,此处仅为校验需要(不能为空和0),设置的大小不起作用,此处设定为固定值1Gi
      storageClassName: csi-obs   # csi-obs是自动创建的OBS存储类,可以根据情况,自定义创建
      volumeName: testing-abc     # PV的名称

    利用pvc_test_abc.yaml创建PVC。

    kubectl create -f pvc_test_abc.yaml

  5. 创建工作负载,并挂载PVC,以Nginx无状态工作负载为例。

    vim obs_deployment_example.yaml

    文件内容如下:

    apiVersion: apps/v1 
    kind: Deployment 
    metadata: 
      name: obs-deployment-example                  # 工作负载名称,可自定义
      namespace: default 
    spec: 
      replicas: 1 
      selector: 
        matchLabels: 
          app: obs-deployment-example              # 标签,可自定义
      template: 
        metadata: 
          labels: 
            app: obs-deployment-example 
        spec: 
          containers: 
          - image: nginx
            name: container-0 
            volumeMounts: 
            - mountPath: /tmp                       # PVC挂载路径,可以根据需求自定义
              name: pvc-obs-example 
          restartPolicy: Always
          imagePullSecrets:
            - name: default-secret
          volumes: 
          - name: pvc-obs-example  
            persistentVolumeClaim: 
              claimName: pvc-test-abc               # PVC名称

    利用obs_deployment_example.yaml创建工作负载obs-deployment-example。

    kubectl create -f obs_deployment_example.yaml

    检查工作负载是否创建成功。

    kubectl get pod

    回显结果如下,若状态为Running,则说明工作负载创建成功。

    NAME                                      READY   STATUS              RESTARTS        AGE
    obs-deployment-example-6b4dfd7b57-frfxv   1/1     Running             0               22h

步骤三:检查Pod对OBS桶的操作权限

基于桶策略,检查账号B创建的Pod实例是否具有相应权限。

  1. 检查Pod能否对账号A创建的OBS桶对象进行读写操作,假设OBS桶中已存在test.txt文件(账号A创建)。

    利用以下命令进入创建的工作负载,Ctrl+d可退出当前负载。
    kubectl -n default exec -it obs-deployment-example-6b4dfd7b57-frfxv -c container-0 /bin/bash

    利用以下命令查看该Pod实例对test.txt的操作权限,“/tmp”为PVC挂载路径。

    ls -l /tmp/test.txt

    回显内容如下,说明该Pod实例对test.txt具有读写权限,这与账户A设置的桶策略相关。

    -rwxrwxrwx 1 root root 4 Sep  5 09:09 /tmp/test.txt

  2. 检查Pod能否对自己创建的OBS桶对象进行读写操作。

    在/tmp路径下创建一个新文件test01.txt,并写入“test\n”
    echo -e "test\n" > /tmp/test01.txt

    利用以下命令查看test01.txt内容,从而验证Pod能否写入和读取自己创建的新对象。此外,账号A也可以在OBS桶中查看新对象。

    cat /tmp/test01.txt

    回显内容如下,说明Pod对自己创建的对象具有读写权限。

    test

步骤四:清理资源

完成该示例的学习后,您可以清理相关资源以避免产生结算费用。如果您打算学习其他示例,请等到完成这些示例后再进行清理。

  1. 利用以下命令删除工作负载。

    kubectl delete -f obs_deployment_example.yaml  

    回显结果如下:

    deployment.apps "obs-deployment-example" deleted

  2. 利用以下命令删除PVC。

    kubectl delete -f pvc_test_abc.yaml  

    回显结果如下:

    persistentvolumeclaim "pvc-test-abc" deleted

  3. 利用以下命令删除PV。

    kubectl delete -f testing_abc.yaml  

    回显结果如下:

    persistentvolume "testing-abc" deleted

  4. 利用以下命令删除Secret。

    kubectl delete -f test_user.yaml  

    回显结果如下:

    secret "test-user" deleted

  5. 利用以下命令删除ConfigMap。

    kubectl delete -f config.yaml  

    回显结果如下:

    configmap "paas-obs-endpoint" deleted

常见问题

若工作负载出现创建不成功的情况,可以根据Pod实例事件中的报错进行排查,具体请参考表6。如果以下思路均不能解决您的问题,请提交工单联系华为云客服为您解答。

表6 工作负载创建不成功的排查思路

报错

原因分析

排查思路

0/4 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/4 nodes are available: 4 Preemption is not helpful for scheduling.

PVC未与PV绑定。

  1. 根据以下命令检查PVC的状态:
    kubectl get pv

    若PVC状态为Pending,则证实PVC未与PV绑定。

  2. 查看PVC详细信息,以确定绑定不成功的具体原因。
    kubectl describe pv <pv_name>
  3. 常见问题如下,可以通过修改YAML文件解决。
    • PVC未绑定正确的PV。
    • PVC与PV的参数未对应,如fsType(需要一致)、StorageClass(需要一致,并保证挂载的StorageClass为对象存储类型)、accessModes(都需要设置为ReadWriteMany,因为OBS只支持该访问模式)以及storage(PVC请求的storage必须小于或等于PV提供的storage)等。

MountVolume.SetUp failed for volume "obs-cce-example": rpc error: code = Unknown desc = failed to get secret(paas.longaksk), err: get secret(paas.longaksk) failed: get secret paas.longaksk from namespace kube-system failed: secrets "paas.longaksk" not found

挂载存储卷时无法找到所需的Secret。

  1. 检查挂载的Secret是否存在。
    kubectl get secret

    若存在,则说明Secret被错误配置。若不存在,请参见创建Secret

  2. 检查Secret的配置参数,常见问题如下:
    • access.key和secret.key未设置为base64编码后的AK和SK。
    • type未设置为cfe/secure-opaque。

MountVolume.SetUp failed for volume "pv-obs-example": rpc error: code = Internal desc = [8032c354-4e1b-41b0-81ce-9d4b3f8c49c9] get obsUrl failed before mount bucket obs-cce-example, get configMap paas-obs-endpoint from namespace kube-system failed: configmaps "paas-obs-endpoint" not found

存储OBS访问端点的ConfigMap不存在或配置不正确。

  1. 检查ConfigMap是否存在。
    kubectl get configmap

    若存在,则说明ConfigMap被错误配置。若不存在,请参见创建ConfigMap

  2. 检查ConfigMap的配置参数,常见问题如下:
    • name未设置为paas-obs-endpoint。
    • namenspace未设置为系统命名空间kube system。
    • 区域名称未设置为OBS所在区域。