管理对象存储

存储桶命名准则

存储分区名称必须遵循以下命名惯例:

  • 在项目中必须是唯一的。项目会向存储桶名称添加唯一的前缀,以确保组织内不会发生冲突。如果出现组织间前缀和存储桶名称冲突的极小概率事件,存储桶创建会失败并显示 bucket name in use 错误。
  • 至少包含 1 个字符,且不得超过 57 个字符。
  • 请勿包含任何个人身份信息 (PII)。
  • 符合 DNS 规范。
  • 以字母开头,且只能包含字母、数字和连字符。

安装 s3cmd 工具 CLI

s3cmd 工具是一个用于管理对象存储的命令行工具。

  1. 如需下载该工具,请前往提取 GDC 软件包的目录。
  2. 运行以下命令,将 s3cmd 映像 s3cmd.tar.tar.gz 提取到空的临时目录:

    tmpdir=$(mktemp -d)
    
    gdcloud artifacts extract oci/ $tmpdir \
      --image-name=$(gdcloud artifacts tree oci | grep s3cmd.tar | sed 's/^.* //')
    
  3. scp tar 文件复制到使用 s3cmd 进行对象操作的客户端机器;解压缩并安装映像。

选择以下安装方法之一来安装 s3cmd 工具:

通过 tar 文件进行安装

  1. 如需解压缩归档文件并安装 s3cmd 软件包,请运行以下命令。您必须拥有 Python distutils 模块才能安装该软件包。该模块通常是核心 Python 软件包的一部分,您也可以使用软件包管理器安装它。

    tar xvf /tmp/gpc-system-tar-files/s3cmd.tar.tar.gz
    cd /tmp/gpc-system-tar-files/s3cmd
    sudo python3 setup.py install
    
  2. 可选:清理下载的文件:

    rm /tmp/gpc-system-tar-files/s3cmd.tar.tar.gz
    rm -r /tmp/gpc-system-tar-files/s3cmd
    

使用 Docker 映像进行安装

  1. 如需安装 s3cmd 映像,请运行以下命令:

    docker load --input s3cmd-docker.tar
    export S3CFG=/EMPTY_FOLDER_PATH/
    alias s3cmd="docker run -it --net=host --mount=type=bind,source=/$S3CFG/,target=/g/
    s3cmd-docker:latest -c /g/s3cfg"
    
  2. 可选:清理下载的文件:

    rm s3cmd-docker.tar
    
  3. 将导出和别名添加到 .bashrc 文件,以便在重启客户端后保持不变。

配置 s3cmd 工具

使用 s3cmd 工具进行基于对象的操作。

运行 s3cmd --configure 命令并指定以下内容:

  1. 访问密钥:输入从获取访问凭据中的 Secret 获取的访问密钥。
  2. Secret Key:输入从获取访问凭据中的 Secret 获取的 Secret Key。
  3. 默认区域:按 ENTER
  4. S3 端点:输入您的基础设施运营商 (IO) 提供的端点。
  5. 对于 DNS 样式存储分区命名,请输入 s3://%(bucket)
  6. 可选:输入加密密码,以保护传输中的文件。
  7. 在“GPG 的路径”中,输入 /usr/bin/gpg
  8. 输入 Yes 以使用 HTTPS 协议。
  9. Enter 可跳过输入代理服务器名称。

创建存储桶

准备工作

项目命名空间用于管理根管理员集群中的存储桶资源。您必须拥有项目才能创建存储桶。 如需创建新项目,请参阅创建项目。您必须拥有适当的存储桶权限才能执行以下操作。请参阅授予存储桶访问权限

创建存储桶

如需创建存储桶,请将存储桶规范应用于项目命名空间:

    kubectl apply -f bucket.yaml

以下是分桶规范的示例:

    apiVersion: object.gdc.goog/v1alpha1
    kind: Bucket
    metadata:
      name: BUCKET_NAME
      namespace: NAMESPACE_NAME
    spec:
      description: DESCRIPTION
      storageClass: standard-rwo
      bucketPolicy :
        lockingPolicy :
          defaultObjectRetentionDays: RETENTION_DAY_COUNT

如需了解详情,请参阅 Bucket API 参考文档

列出存储分区

如需列出您在给定对象存储租户中有权访问的所有存储分区,请完成以下步骤:

  1. 运行以下命令以列出所有存储分区:

    kubectl get buckets --all-namespaces
    kubectl get buckets --namespace NAMESPACE_NAME
    

删除存储桶

您可以使用 CLI 删除存储分区。必须先清空存储分区,然后才能将其删除。

  1. 使用查看存储桶配置部分中的 GETDESCRIBE 命令获取完全限定的存储桶名称。

  2. 如果相应存储桶不为空,请清空该存储桶:

    s3cmd rm --recursive -—force s3://FULLY_QUALIFIED_BUCKET_NAME
    
  3. 删除空存储桶:

    kubectl delete buckets/BUCKET_NAME --namespace NAMESPACE_NAME
    

查看存储桶配置

使用任一命令可查看存储桶的配置详细信息:

    kubectl describe buckets/BUCKET_NAME --namespace NAMESPACE_NAME
    kubectl get buckets/BUCKET_NAME --namespace NAMESPACE_NAME -o yaml

设置对象保留期限

默认情况下,您可以随时删除对象。启用对象锁定功能并设置保留期限,以防止存储桶中的所有对象在指定天数内被删除。您必须先删除保留期限过后保留的所有对象,然后才能删除存储桶。

您必须在创建存储桶时启用对象锁定。创建存储桶后,您将无法启用或停用对象锁定功能。不过,您可以修改默认的对象保留期限。

您可以创建存储桶,也可以在创建存储桶时启用对象锁定。如果您已启用对象锁定,则可以选择指定默认保留期限。

如需修改保留期限,请更新存储分区资源中的 Bucket.spec.bucketPolicy.lockingPolicy.defaultObjectRetentionDays 字段。

以下是更新存储分区资源中的字段的示例:

apiVersion: object.gdc.goog/v1alpha1
kind: Bucket
metadata:
  name: BUCKET_NAME
  namespace: NAMESPACE_NAME
spec:
  description: "This bucket has a default retention period specified."
  storageClass: standard-rwo
  bucketPolicy :
    lockingPolicy :
      defaultObjectRetentionDays: RETENTION_DAY_COUNT
---
apiVersion: object.gdc.goog/v1alpha1
kind: Bucket
metadata:
  name: BUCKET_NAME
  namespace: NAMESPACE_NAME
spec:
  description: "This would enable object locking but not specify a default retention period."
  storageClass: standard-rwo
  bucketPolicy :
    lockingPolicy :
---
apiVersion: object.gdc.goog/v1alpha1
kind: Bucket
metadata:
  name: BUCKET_NAME
  namespace: NAMESPACE_NAME
spec:
  description: "This bucket does not have locking or retention enabled."
  storageClass: standard-rwo

对保留期限的任何更新都适用于更新后在相应存储桶中创建的对象。对于现有对象,保留期限不会发生变化。

启用对象锁定后,如果您尝试覆盖某个对象,系统会添加该对象的新版本。您可以检索这两个对象版本。 如需详细了解如何列出对象版本,请参阅 Amazon Web Services 文档中的 ListObjectVersionshttps://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html

如需创建一次写入多次读取 (WORM) 存储桶,请参阅 WORM 存储桶部分。

授予存储桶访问权限

您可以通过创建和应用具有预定义角色的 RoleBindings,向其他用户或服务账号提供存储桶访问权限。

预定义角色

  • project-bucket-object-viewer::此角色允许用户列出项目中的所有存储桶、列出这些存储桶中的对象,以及读取对象和对象元数据。此角色不允许您对对象执行写入操作,例如上传、覆盖或删除

  • project-bucket-object-admin::此角色允许用户列出项目中的所有存储桶,并对对象执行写入和读取操作,例如上传、覆盖或删除。

  • project-bucket-admin::此角色允许用户管理给定命名空间中的所有存储桶,以及这些存储桶中的所有对象。

如需查看这些角色授予的权限的完整列表,请参阅预设角色权限部分。

如需获得创建项目角色绑定的权限,请让您的项目 IAM 管理员向您授予项目 IAM 管理员 (project-iam-admin) 角色。

以下示例展示了如何创建 RoleBinding 以向用户和服务账号授予访问权限:

  1. 在您的系统上创建一个 YAML 文件,例如 rolebinding-object-admin-all-buckets.yaml

     apiVersion: rbac.authorization.k8s.io/v1
     kind: RoleBinding
     metadata:
       namespace: NAMESPACE_NAME
       name: readwrite-all-buckets
     roleRef:
       kind: Role
       name: project-bucket-object-admin
       apiGroup: rbac.authorization.k8s.io
     subjects:
     - kind: ServiceAccount
       namespace: NAMESPACE_NAME
       name: SA_NAME
     - kind: User
       namespace: NAMESPACE_NAME
       name: bob@example.com  # Could be bob or bob@example.com based on your organization settings.
       apiGroup: rbac.authorization.k8s.io
     ```
    
  2. 应用 YAML 文件:

    kubectl apply \
    -f rolebinding-object-admin-all-buckets.yaml
    

获取存储桶访问凭据

当您授予对存储桶的访问权限时,访问凭据会在 Secret 中创建。

Secret 名称的格式为 object-storage-key-SUBJECT_TYPE-SUBJECT_HASH

  • SUBJECT_TYPE 的值如下:
    • user:用户。
    • saServiceAccount
  • SUBJECT_HASH 是正文名称的 base32 编码 SHA256 哈希值。

例如,用户 bob@foo.com 拥有名为以下内容的 Secret:

object-storage-key-user-oy6jdqd6bxfoqcecn2ozv6utepr5bgh355vfku7th5pmejqubdja

访问用户密钥

对于用户正文,Secret 位于根管理员集群中的 object-storage-access-keys 命名空间中。

  1. 查找密钥名称:

    kubectl auth can-i --list --namespace object-storage-access-keys | grep object-storage-key-
    

    您将收到类似如下所示的输出:

    secrets        []        [object-storage-key-nl-user-oy6jdqd6bxfoqcecn2ozv6utepr5bgh355vfku7th5pmejqubdja,object-storage-key-std-user-oy6jdqd6bxfoqcecn2ozv6utepr5bgh355vfku7th5pmejqubdja]        [get]
    
  2. 获取相应 Secret 的内容以访问存储分区:

    kubectl get -o yaml --namespace object-storage-access-keys secret
    object-storage-key-rm-user-oy6jdqd6bxfoqcecn2ozv6utepr5bgh355vfku7th5pmejqubdja
    

    您将收到类似如下所示的输出:

    data:
      access-key-id: MEhYM08wWUMySjcyMkVKTFBKRU8=
      create-time: MjAyMi0wNy0yMiAwMTowODo1OS40MTQyMTE3MDMgKzAwMDAgVVRDIG09KzE5OTAuMzQ3OTE2MTc3
      secret-access-key: Ump0MVRleVN4SmhCSVJhbmlnVDAwbTJZc0IvRlJVendqR0JuYVhiVA==
    
  3. 解码访问密钥 ID 和密钥:

    echo "MEhYM08wWUMySjcyMkVKTFBKRU8=" | base64 -d \
        && echo \
        && echo "Ump0MVRleVN4SmhCSVJhbmlnVDAwbTJZc0IvRlJVendqR0JuYVhiVA==" | base64 -d
    

    您将收到类似如下所示的输出:

    0HX3O0YC2J722EJLPJEO
    Rjt1TeySxJhBIRanigT00m2YsB/FRUzwjGBnaXbT
    
  4. 按照配置 s3cmd 部分中的信息操作。

访问服务账号密钥

对于服务账号 (SA) 正文,Secret 与存储桶位于同一命名空间中。如需查找名称,请运行以下命令:

  kubectl get --namespace NAMESPACE_NAME secrets -o=jsonpath=
  '{.items[?(@.metadata.annotations.object\.gdc\.goog/subject=="SA_NAME")].metadata.name}'

您将收到类似如下所示的输出:

  object-storage-key-rm-sa-mng3olp3vsynhswzasowzu3jgzct2ert72pjp6wsbzqhdwckwzbq

您可以在 pod 中将 Secret 引用为环境变量 (https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables) 或文件 (https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod)。

预设角色权限

project-bucket-object-viewer 权限

此角色授予以下权限:获取和列出存储桶中的对象以及对象的元数据。

project-bucket-object-viewer 角色具有以下权限:

  • 存储分区 API 权限

    1. 获取
    2. 列表
    3. 观看
  • S3 对象存储权限

    1. GetObject
    2. GetObjectAcl
    3. GetObjectVersion
    4. ListBucket
    5. ListBucketVersions
    6. ListBucketMultipartUploads
    7. ListMultipartUploadParts

project-bucket-object-admin 权限

此角色授予在存储桶中放置和删除对象、对象版本和标记的权限。此外,它还会授予 project-bucket-object-viewer 中的所有权限。

project-bucket-object-admin 角色具有以下对象存储权限:

  • S3 对象存储权限

    1. AbortMultipartUpload
    2. DeleteObject
    3. DeleteObjectVersion
    4. PutObject
    5. RestoreObject

project-bucket-admin 权限

此角色授予在项目命名空间中创建、更新或删除 Bucket 资源的权限。此外,它还会授予 project-bucket-object-admin 中的所有权限。

project-bucket-object-admin 角色具有以下权限:

  • 存储分区 API 权限

    1. 创建
    2. 更新
    3. 删除

创建 WORM 存储分区

WORM 存储桶可确保没有其他内容会覆盖对象,并确保对象至少保留一段时间。审核日志记录是 WORM 存储桶的一个使用场景示例。

请按以下步骤创建 WORM 存储桶:

  1. 在创建存储桶时设置保留期限。例如,以下示例存储桶的保留期限为 365 天。

    apiVersion: object.gdc.goog/v1alpha1
    kind: Bucket
    metadata:
      name: foo logging-bucket
      namespace: foo-service
    spec:
      description: "Audit logs for foo"
      storageClass: standard-rwo
      bucketPolicy :
        lockingPolicy :
          defaultObjectRetentionDays: 365
    
  2. 向需要只读访问权限的所有用户授予 project-bucket-object-viewer 角色:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      namespace: foo-service
      name: object-readonly-access
    roleRef:
      kind: Role
      name: project-bucket-object-viewer
      apiGroup: rbac.authorization.k8s.io
    subjects:
    - kind: ServiceAccount
      namespace: foo-service
      name: foo-log-processor
    - kind: User
      name: bob@example.com
      apiGroup: rbac.authorization.k8s.io
    
  3. 向需要向存储桶写入内容的用户授予 project-bucket-object-admin 角色:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      namespace: foo-service
      name: object-write-access
    roleRef:
      kind: Role
      name: project-bucket-object-viewer
      apiGroup: rbac.authorization.k8s.io
    subjects:
    - kind: ServiceAccount
      namespace: foo-service
      name: foo-service-account
    

从对象存储恢复到块存储上的文件系统

分配永久性卷

如需从对象存储端点恢复文件,请按以下步骤操作:

  1. 在恢复操作中,为目标分配一个永久性卷 (PV)。使用持久卷声明 (PVC) 来分配卷,如以下示例所示:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: restore-pvc
      namespace: restore-ns
    spec:
      storageClassName: standard-rwo
      accessModes:
    ReadWriteOnce
      resources:
        requests:
          storage: 1Gi # Need sufficient capacity for full restoration.
    
  2. 检查 PVC 的状态:

    kubectl get pvc restore-pvc -n restore-ns
    

    当 PVC 处于 Bound 状态时,便可在重新水合它的 Pod 中使用。

  3. 如果 Stateful 集最终会使用 PV,您必须匹配渲染的 StatefulSet PVC。StatefulSet 生成的 pod 会使用已完成水合的卷。以下示例展示了名为 ss 的 StatefulSet 中的卷声明模板。

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: standard-rwo
          resources:
            requests:
              storage: 1Gi
    
  4. 预先分配名称为 ss-pvc-name-0ss-pvc-name-1 等的 PVC,以确保生成的 Pod 使用预先分配的卷。

为永久性卷 (PV) 补充水分

在 PVC 绑定到 PV 后,启动 Job 以填充 PV:

apiVersion: batch/v1
kind: Job
metadata:
  name: transfer-job
  namespace: transfer
spec:
  template:
    spec:
      serviceAccountName: data-transfer-sa
      volumes:
      - name: data-transfer-restore-volume
        persistentVolumeClaim:
          claimName: restore-pvc
      containers:
      - name: storage-transfer-pod
        image: gcr.io/private-cloud-staging/storage-transfer:latest
        command: /storage-transfer
        args:
        - --src_endpoint=https://your-src-endpoint.com
        - --src_path=/your-src-bucket
        - --src_credentials=transfer/src-secret
        - --dst_path=/restore-pv-mnt-path
        - --src_type=s3
        - --dst_type=local
      volumeMounts:
      - mountPath: /restore-pv-mnt-path
        name: data-transfer-restore-volume

Job 运行完毕后,对象存储桶中的数据会填充卷。另一个 pod 可以使用相同的标准机制来装载卷,从而使用该数据。