Gerenciar o armazenamento de objetos

Diretrizes de nomenclatura de buckets de armazenamento

Os nomes de bucket precisam seguir estas convenções de nomenclatura:

  • Ser exclusivo no projeto. Um projeto adiciona um prefixo exclusivo ao nome do bucket, garantindo que não haja conflitos na organização. No caso improvável de um conflito entre um prefixo e um nome de bucket em várias organizações, a criação do bucket falha com um erro bucket name in use.
  • Ter pelo menos um e no máximo 57 caracteres.
  • Não inclua informações de identificação pessoal (PII).
  • Estar em conformidade com o DNS.
  • Começar com uma letra e conter apenas letras, números e hifens.

Instalar a CLI da ferramenta s3cmd

A ferramenta s3cmd é uma ferramenta de linha de comando para gerenciar o armazenamento de objetos.

  1. Para fazer o download da ferramenta, navegue até o diretório de onde o pacote do GDC foi extraído.
  2. Execute os comandos a seguir para extrair a imagem s3cmd, s3cmd.tar.tar.gz, para um diretório temporário vazio:

    tmpdir=$(mktemp -d)
    
    gdcloud artifacts extract oci/ $tmpdir \
      --image-name=$(gdcloud artifacts tree oci | grep s3cmd.tar | sed 's/^.* //')
    
  3. scp o arquivo tar em uma máquina cliente em que você usa s3cmd para operações de objeto. Descompacte e instale a imagem.

Escolha um dos seguintes métodos de instalação para instalar a ferramenta s3cmd:

Instalar usando um arquivo tar

  1. Para descompactar o arquivo e instalar o pacote s3cmd, execute os seguintes comandos. É necessário ter o módulo distutils do Python para instalar o pacote. O módulo geralmente faz parte do pacote principal do Python ou pode ser instalado usando o gerenciador de pacotes.

    tar xvf /tmp/gpc-system-tar-files/s3cmd.tar.tar.gz
    cd /tmp/gpc-system-tar-files/s3cmd
    sudo python3 setup.py install
    
  2. Opcional: limpe os arquivos baixados:

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

Instalar com imagem do Docker

  1. Para instalar a imagem s3cmd, execute os seguintes comandos:

    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. Opcional: limpe os arquivos baixados:

    rm s3cmd-docker.tar
    
  3. Adicione a exportação e o alias ao arquivo .bashrc para que eles persistam após reiniciar o cliente.

Configurar a ferramenta s3cmd

Use a ferramenta s3cmd para operações baseadas em objetos.

Execute o comando s3cmd --configure e especifique o seguinte:

  1. Chave de acesso: insira a chave de acesso obtida do secret em Como receber credenciais de acesso.
  2. Chave secreta: insira a chave secreta obtida do secret em Como receber credenciais de acesso.
  3. Região padrão: pressione ENTER.
  4. Endpoint do S3: insira o endpoint fornecido pelo operador de infraestrutura (IO).
  5. Para nomeação de buckets no estilo DNS, insira s3://%(bucket).
  6. Opcional: insira uma senha de criptografia para proteger os arquivos em trânsito.
  7. Em "Caminho para GPG", insira /usr/bin/gpg.
  8. Insira Yes para usar o protocolo HTTPS.
  9. Pressione Enter para pular a inserção do nome do servidor proxy.

Criar buckets de armazenamento

Antes de começar

Um namespace de projeto gerencia recursos de bucket no cluster de administrador raiz. Você precisa ter um projeto para criar um bucket. Para criar um novo projeto, consulte Criar um projeto. Você precisa ter as permissões de bucket adequadas para realizar as seguintes operações. Consulte como conceder acesso ao bucket.

Criar um bucket

Para criar um bucket, aplique uma especificação ao namespace do projeto:

    kubectl apply -f bucket.yaml

Confira um exemplo de especificação de bucket:

    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

Para mais detalhes, consulte a referência da API Bucket.

Listar buckets de armazenamento

Para listar todos os buckets a que você tem acesso em um determinado locatário de armazenamento de objetos, siga estas etapas:

  1. Execute os comandos a seguir para listar todos os buckets:

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

Excluir buckets de armazenamento

É possível excluir buckets de armazenamento usando a CLI. Os buckets precisam estar vazios antes de serem excluídos.

  1. Use o comando GET ou DESCRIBE na seção Ver configuração do bucket para receber o nome totalmente qualificado do bucket.

  2. Se o bucket não estiver vazio, esvazie-o:

    s3cmd rm --recursive -—force s3://FULLY_QUALIFIED_BUCKET_NAME
    
  3. Exclua o bucket vazio:

    kubectl delete buckets/BUCKET_NAME --namespace NAMESPACE_NAME
    

Ver a configuração do bucket

Use um dos comandos para conferir os detalhes da configuração de um bucket:

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

Definir um período de armazenamento de objetos

Por padrão, você pode excluir objetos a qualquer momento. Ative o bloqueio de objetos com um período de armazenamento para evitar que todos os objetos no bucket sejam excluídos por o número de dias especificado. Não é possível excluir um bucket até que você exclua todos os objetos após o período de armazenamento.

Você precisa ativar o bloqueio de objetos ao criar o bucket. Não é possível ativar ou desativar o bloqueio de objetos depois de criar um bucket. No entanto, é possível modificar o período de armazenamento padrão de objetos.

É possível criar um bucket com ou sem ativar o bloqueio de objetos. Se você tiver ativado o bloqueio de objetos, especificar um período de armazenamento padrão será opcional.

Para modificar o período de armazenamento, atualize o campo Bucket.spec.bucketPolicy.lockingPolicy.defaultObjectRetentionDays no recurso "Bucket".

Confira um exemplo de atualização do campo no recurso "Bucket":

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

Todas as atualizações no período de armazenamento se aplicam a objetos criados no bucket após a atualização. Para objetos preexistentes, o período de armazenamento não muda.

Quando o bloqueio de objetos está ativado, se você tentar substituir um objeto, uma nova versão dele será adicionada. É possível recuperar as duas versões do objeto. Para detalhes sobre como listar versões de objetos, consulte ListObjectVersions na documentação do Amazon Web Services: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html

Para criar um bucket de gravação única e várias leituras (WORM), consulte a seção Bucket WORM.

Conceder acesso ao bucket

Você pode conceder acesso ao bucket a outros usuários ou contas de serviço criando e aplicando RoleBindings com papéis predefinidos.

Papéis predefinidos

  • project-bucket-object-viewer::permite que um usuário liste todos os buckets no projeto, liste objetos nesses buckets e leia objetos e metadados de objetos. Essa função não permite operações de gravação em objetos, como upload, substituição ou exclusão.

  • project-bucket-object-admin::esse papel permite que um usuário liste todos os buckets no projeto e faça operações de leitura e gravação em objetos, como upload, substituição ou exclusão.

  • project-bucket-admin::permite que os usuários gerenciem todos os buckets no namespace especificado, bem como todos os objetos nesses buckets.

Para conferir uma lista completa das permissões concedidas para esses papéis, consulte a seção permissões de papéis predefinidos.

Para receber as permissões necessárias para criar vinculações de função do projeto, peça ao administrador do IAM do projeto para conceder a você a função de administrador do IAM do projeto (project-iam-admin).

Confira um exemplo de criação de um RoleBinding para conceder acesso a um usuário e uma conta de serviço:

  1. Crie um arquivo YAML no seu sistema, como 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. Aplique o arquivo YAML:

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

Receber credenciais de acesso ao bucket

Quando você concede acesso a um bucket, as credenciais de acesso são criadas em um Secret.

O formato do nome do secret é object-storage-key-SUBJECT_TYPE-SUBJECT_HASH.

  • Os valores para SUBJECT_TYPE são:
    • user: o usuário.
    • sa: o ServiceAccount.
  • SUBJECT_HASH é o hash SHA256 codificado em base32 do nome do assunto.

Por exemplo, o usuário bob@foo.com tem o secret chamado:

object-storage-key-user-oy6jdqd6bxfoqcecn2ozv6utepr5bgh355vfku7th5pmejqubdja

Acessar a chave secreta do usuário

Para um assunto do usuário, o Secret está no namespace object-storage-access-keys no cluster de administrador raiz.

  1. Encontre o nome do secret:

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

    Você vai receber uma saída parecida com esta:

    secrets        []        [object-storage-key-nl-user-oy6jdqd6bxfoqcecn2ozv6utepr5bgh355vfku7th5pmejqubdja,object-storage-key-std-user-oy6jdqd6bxfoqcecn2ozv6utepr5bgh355vfku7th5pmejqubdja]        [get]
    
  2. Receba o conteúdo do secret correspondente para acessar os buckets:

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

    Você vai receber uma saída parecida com esta:

    data:
      access-key-id: MEhYM08wWUMySjcyMkVKTFBKRU8=
      create-time: MjAyMi0wNy0yMiAwMTowODo1OS40MTQyMTE3MDMgKzAwMDAgVVRDIG09KzE5OTAuMzQ3OTE2MTc3
      secret-access-key: Ump0MVRleVN4SmhCSVJhbmlnVDAwbTJZc0IvRlJVendqR0JuYVhiVA==
    
  3. Decodifique o ID da chave de acesso e o segredo:

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

    Você vai receber uma saída parecida com esta:

    0HX3O0YC2J722EJLPJEO
    Rjt1TeySxJhBIRanigT00m2YsB/FRUzwjGBnaXbT
    
  4. Siga a seção Configurar s3cmd com as informações resultantes.

Acessar o secret da conta de serviço

Para um assunto de conta de serviço (SA, na sigla em inglês), o secret está no mesmo namespace do bucket. Para encontrar o nome, execute:

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

Você vai receber uma saída parecida com esta:

  object-storage-key-rm-sa-mng3olp3vsynhswzasowzu3jgzct2ert72pjp6wsbzqhdwckwzbq

É possível fazer referência ao Secret no pod como variáveis de ambiente (https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables) ou arquivos (https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod).

Permissões de função predefinidas

Permissões de visualizador de objetos de bucket do projeto

Essa função concede permissões para receber e listar objetos e metadados de objetos no bucket.

O papel project-bucket-object-viewer tem estas permissões:

  • Permissões da API de bucket:

    1. Get
    2. Lista
    3. ASSISTIR
  • Permissões de armazenamento de objetos do S3:

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

permissões de administrador de objetos e buckets do projeto

Esse papel concede permissões para inserir e excluir objetos, versões de objetos e tags no bucket. Além disso, ela também concede todas as permissões em project-bucket-object-viewer.

O papel project-bucket-object-admin tem as seguintes permissões de armazenamento de objetos:

  • Permissões de armazenamento de objetos do S3:

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

permissões de administrador de bucket do projeto

Essa função concede permissões para criar, atualizar ou excluir recursos Bucket no namespace do projeto. Além disso, ela também concede todas as permissões em project-bucket-object-admin.

O papel project-bucket-object-admin tem estas permissões:

  • Permissões da API de bucket:

    1. Criar
    2. Atualizar
    3. Excluir

Criar um bucket WORM

Um bucket WORM garante que nada mais substitua os objetos e os retém por um período mínimo. O registro de auditoria é um exemplo de caso de uso para um bucket WORM.

Siga estas etapas para criar um bucket WORM:

  1. Defina um período de armazenamento ao criar o bucket. Por exemplo, o bucket de exemplo a seguir tem um período de armazenamento de 365 dias.

    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. Conceda a função project-bucket-object-viewer a todos os usuários que precisam de acesso somente leitura:

    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. Conceda a função project-bucket-object-admin aos usuários que precisam gravar conteúdo no bucket:

    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
    

Restaurar do armazenamento de objetos para o sistema de arquivos no armazenamento em blocos

Alocar um volume permanente

Para restaurar arquivos de um endpoint de armazenamento de objetos, siga estas etapas:

  1. Alocar um volume permanente (PV) para o destino na restauração. Use uma reivindicação de volume persistente (PVC) para alocar o volume, conforme mostrado no exemplo a seguir:

    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. Verifique o status da PVC:

    kubectl get pvc restore-pvc -n restore-ns
    

    Depois que o PVC estiver no estado Bound, ele estará pronto para ser consumido no pod que o reidrata.

  3. Se um conjunto Stateful consumir o PV, você precisará corresponder aos PVCs do StatefulSet renderizados. Os pods que StatefulSet produz consomem os volumes hidratados. O exemplo a seguir mostra modelos de reivindicação de volume em um StatefulSet chamado ss.

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: standard-rwo
          resources:
            requests:
              storage: 1Gi
    
  4. Pré-aloque PVCs com nomes como ss-pvc-name-0 e ss-pvc-name-1 para garantir que os pods resultantes consumam os volumes pré-alocados.

Hidratar o volume permanente (PV)

Depois que a PVC for vinculada a um PV, inicie o Job para preencher o 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

Depois que o Job terminar de ser executado, os dados do bucket de armazenamento de objetos vão preencher o volume. Um pod separado pode consumir os dados usando os mesmos mecanismos padrão para montar um volume.