跨账号挂载对象存储
应用场景
- 跨账号数据共享。例如,公司内部多团队需要共享数据,但不同团队使用不同的账号。
- 跨账户数据迁移和备份。例如,账号A即将停用,所有的数据需要迁移至账户B。
- 数据处理与分析。例如,账号B是外部数据处理商,需要访问账户A的原始数据进行大数据分析和机器学习等操作。
通过跨账户挂载对象存储,您可以实现数据共享,降低存储和传输成本,同时确保数据的安全性和一致性。这种方式使多个团队或组织能够安全、便捷地访问彼此的数据资源,避免重复存储和冗余传输,同时确保数据的最新性和合规性,从而提升整体的业务效率和安全性。
操作流程
前提条件
- 涉及账户在同一区域内。
- 已创建一个安装CCE容器存储(Everest)的集群,其中要求Everest版本≥1.1.11,集群版本≥1.15。若没有可用集群 ,请参照购买Standard/Turbo集群创建。
- 集群所在VPC下,已创建绑定弹性公网IP的ECS虚拟机,且该ECS通过kubectl连接集群。若没有连接集群,请参照通过kubectl连接集群。
步骤一:创建OBS桶策略和桶ACL
账户A对OBS配置桶策略和桶ACL,授予账号B相应的权限(如读写权限)。
- 登录OBS管理控制台,左侧导航栏选择“桶列表”。
- 在“桶列表”中,单击待操作桶,进入“对象”页面。
- 在左侧导航栏,单击“权限控制 > 桶策略”,单击“创建”,进入“创建桶策略”页面。
- 配置相关参数。本示例仅解释必要参数,其余保留默认值。关于配置参数的详细说明请参见桶策略。
表2 桶策略参数配置 参数
参数说明
示例
策略名称
自定义名称。
example01
效力
用于指定策略的行为。
- 允许:表示允许策略中定义的操作。
- 拒绝:表示拒绝策略中定义的操作。
允许
被授权用户
用于指定被授权账户(可多选)。对于不同类型的授权账户,OBS控制台在授权操作中预置了不同的模板配置,具体请参见使用模板创建桶策略。
- 所有账户:任何账户不通过身份认证即可执行当前桶策略,数据可能存在安全风险。
- 当前账户:授权当前账户下的特定IAM账户。
- 其他账户:授权其他账户下的特定IAM账户。
其他账户
XXX(账户ID)/XXX(IAM ID)
授权资源
用于指定授权的资源范围。
- 整个桶(包括桶内对象):允许被授权账户对整个桶和桶内的所有对象进行操作。
- 当前桶:仅允许被授权账户对整个桶进行操作。
- 指定对象:仅允许被授权账户对桶内特定对象进行操作。
整个桶(包括桶内对象)
授权操作
用于指定授权的具体操作。
- 模板配置:OBS控制台预置的权限配置模板。当选择“桶读写”时,高级设置默认“排除以上授权操作”。
- 自定义配置:自定义选择授权的具体操作。
模板配置 > 桶读写
图2 创建桶策略
- 在左侧导航栏,单击“权限控制 > 桶ACL”,单击“用户权限 > 增加”,输入授权用户的账号ID,“桶访问权限”勾选“读取权限”和“写入权限”,“对象权限”勾选“对象读权限”,“ACL访问权限”勾选“读取权限”和“写入权限”,单击“确定”。
步骤二:创建挂载OBS的工作负载
基于账号A的OBS,账号B创建对应的PV和PVC,并将PVC挂载到需要的工作负载中。
- 创建名为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对应的值请参见地区和终端节点。
{"cn-south-4": "https://obs.cn-south-4.myhuaweicloud.com:443", "cn-north-4": "https://obs.cn-north-4.myhuaweicloud.com:443"}
- 创建名为test-user的Secret,名称可自定义,用于在CSI挂载卷时提供访问凭证。
- 获取访问密钥。返回控制台,鼠标指向界面右上角的登录用户名,在下拉列表中单击“我的凭证”。
在左侧导航栏单击“访问密钥”,单击“新增访问密钥”,进入“新增访问密钥”页面。
单击“确定”,下载访问密钥。
- 对访问密钥进行base64编码(假设上文获取到的AK为“xxx”,SK为“yyy”),并记录编码后的AK和SK。
echo -n xxx|base64 echo -n yyy|base64
- 新建一个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
- 获取访问密钥。返回控制台,鼠标指向界面右上角的登录用户名,在下拉列表中单击“我的凭证”。
- 创建名为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,避免级联删除底层卷。
- 创建名为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
- 创建工作负载,并挂载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实例是否具有相应权限。
- 检查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
- 检查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
步骤四:清理资源
完成该示例的学习后,您可以清理相关资源以避免产生结算费用。如果您打算学习其他示例,请等到完成这些示例后再进行清理。
- 利用以下命令删除工作负载。
kubectl delete -f obs_deployment_example.yaml
回显结果如下:
deployment.apps "obs-deployment-example" deleted
- 利用以下命令删除PVC。
kubectl delete -f pvc_test_abc.yaml
回显结果如下:
persistentvolumeclaim "pvc-test-abc" deleted
- 利用以下命令删除PV。
kubectl delete -f testing_abc.yaml
回显结果如下:
persistentvolume "testing-abc" deleted
- 利用以下命令删除Secret。
kubectl delete -f test_user.yaml
回显结果如下:
secret "test-user" deleted
- 利用以下命令删除ConfigMap。
kubectl delete -f config.yaml
回显结果如下:
configmap "paas-obs-endpoint" deleted
常见问题
若工作负载出现创建不成功的情况,可以根据Pod实例事件中的报错进行排查,具体请参考表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绑定。 |
|
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。 |
|
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不存在或配置不正确。 |
|