Ativar buckets do Cloud Storage como volumes temporários do CSI

Este guia mostra como usar volumes temporários de CSI com suporte dos buckets do Cloud Storage para gerenciar automaticamente os recursos de armazenamento dos pods ou jobs do Kubernetes no Google Kubernetes Engine (GKE). Os volumes temporários de CSI estão vinculados ao ciclo de vida do pod ou do job, e não é necessário processar manualmente os objetos PersistentVolume e PersistentVolumeClaim.

Este guia é destinado a administradores e operadores de plataforma que querem simplificar o gerenciamento de armazenamento dos aplicativos do GKE.

Antes de ler esta página, você precisa estar familiarizado com volumes temporários de CSI, pods e jobs do Kubernetes e buckets do Cloud Storage.

Se você já conhece os PersistentVolumes e quer consistência com as implantações atuais que dependem desse tipo de recurso, consulte Montar buckets do Cloud Storage como volumes permanentes.

Antes de começar

Confirme se você concluiu estes pré-requisitos:

Como funciona o armazenamento temporário de CSI para buckets do Cloud Storage

Os volumes temporários de CSI simplificam o gerenciamento de armazenamento dos aplicativos no GKE. Você define volumes temporários de CSI diretamente na especificação do pod ou do job. O uso de volumes temporários de CSI elimina a necessidade de objetos PersistentVolume e PersistentVolumeClaim separados.

O uso de um volume temporário de CSI envolve estas operações:

  1. Definição de armazenamento: especifique o armazenamento no arquivo YAML do pod ou do job, incluindo o driver CSI a ser usado e todos os parâmetros necessários. Para o driver CSI do Cloud Storage FUSE, especifique o nome do bucket e outros detalhes relevantes.

    Opcionalmente, é possível ajustar o desempenho do driver CSI usando o recurso de armazenamento em cache de arquivos. O armazenamento em cache de arquivos pode aumentar o desempenho do app do GKE armazenando em cache os arquivos do Cloud Storage acessados com frequência em um disco mais rápido.

    Além disso, é possível usar o recurso de download paralelo para acelerar a leitura de arquivos grandes do Cloud Storage para downloads multithread. Esse recurso pode ser usado para melhorar os tempos de carregamento de modelos, principalmente para leituras com mais de 1 GB.

  2. Invocação do driver: ao criar o pod ou o job, o GKE detecta a solicitação de volume temporário e chama o driver CSI do Cloud Storage FUSE.

  3. Montagem e anexo de volume: o driver CSI monta o volume temporário de CSI (que aponta para o bucket do Cloud Storage subjacente) e o disponibiliza para o pod ou o job, tornando-o acessível ao aplicativo. Para ajustar como os buckets são montados no sistema de arquivos, use as opções de montagem. Também é possível usar atributos de volume para configurar o comportamento específico do driver CSI do Cloud Storage FUSE.

  4. Gerenciamento do ciclo de vida: o volume temporário existe durante o ciclo de vida do pod ou do job. Quando o pod é excluído ou o job é concluído, o driver CSI processa automaticamente a limpeza e a desmontagem do volume.

Anexar o volume temporário de CSI

Siga estas instruções, dependendo se você quer anexar o volume temporário de CSI a um pod ou job.

Pod

Para anexar o volume temporário de CSI em um pod, siga estas etapas:

  1. Crie um manifesto YAML de pod com a seguinte especificação:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-ephemeral 
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true" 
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - image: busybox
        name: busybox
        command: ["sleep"]
        args: ["infinity"] 
        volumeMounts:
        - name: gcs-fuse-csi-ephemeral
          mountPath: /data
          readOnly: true
      serviceAccountName: KSA_NAME
      volumes:
      - name: gcs-fuse-csi-ephemeral
        csi:
          driver: gcsfuse.csi.storage.gke.io
          readOnly: true
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs" 
    

    Substitua os seguintes valores:

    O manifesto de exemplo mostra estas configurações obrigatórias:

    • metadata.annotations: a anotação gke-gcsfuse/volumes: "true" é obrigatória. Consulte Configurar o contêiner secundário para anotações opcionais.
    • spec.volumes[n].csi.driver: use gcsfuse.csi.storage.gke.io como o nome do driver CSI.

    Opcionalmente, é possível ajustar estas variáveis:

    • spec.terminationGracePeriodSeconds: por padrão, essa opção é definida como 30. Se você precisar gravar arquivos grandes no bucket do Cloud Storage, aumente esse valor para garantir que o Cloud Storage FUSE tenha tempo suficiente para transferir os dados após o encerramento do aplicativo. Para saber mais, consulte Práticas recomendadas do Kubernetes: encerrar com carência.
    • spec.volumes[n].csi.volumeAttributes.mountOptions: transmita as opções de montagem para o Cloud Storage FUSE. Especifique as flags em uma string separada por vírgulas, sem espaços.
    • spec.volumes[n].csi.volumeAttributes: transmita outros atributos de volume para o Cloud Storage FUSE.
    • spec.volumes[n].csi.readOnly: especifique "true" se todas as montagens de volume forem somente leitura.
    • spec.containers[n].volumeMounts[m].readOnly: especifique "true" se apenas uma montagem de volume específica for somente leitura.
  2. Execute o comando a seguir para aplicar o manifesto ao cluster:

    kubectl apply -f FILE_PATH
    

    Substitua FILE_PATH pelo caminho do arquivo YAML.

Pod (armazenamento em cache de arquivos)

Para anexar o volume temporário de CSI com armazenamento em cache de arquivos em um pod, siga estas etapas:

  1. Crie um cluster ou pool de nós com armazenamento temporário via SSD local seguindo as etapas em Criar um cluster ou pool de nós com armazenamento temporário via SSD local.

  2. Crie um manifesto YAML de pod com a seguinte especificação:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-file-cache-example 
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/ephemeral-storage-limit: "50Gi" 
    spec:
      nodeSelector:
        cloud.google.com/gke-ephemeral-storage-local-ssd: "true"
      restartPolicy: Never
      initContainers:
      - name: data-loader
        image: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 1Gi
        command:
          - "/bin/sh"
          - "-c"
          - |
            mkdir -p /test_files
            for i in $(seq 1 1000); do dd if=/dev/zero of=/test_files/file_$i.txt bs=1024 count=64; done
            gcloud storage cp /test_files gs://BUCKET_NAME --recursive
      containers:
      - name: data-validator
        image: busybox
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 500m
            memory: 512Mi
        command:
          - "/bin/sh"
          - "-c"
          - |
            echo "first read with cache miss"
            time cat /data/test_files/file_* > /dev/null
    
            echo "second read from local cache"
            time cat /data/test_files/file_* > /dev/null 
        volumeMounts:
        - name: gcs-fuse-csi-ephemeral
          mountPath: /data
      serviceAccountName: KSA_NAME
      volumes:
      - name: gcs-fuse-csi-ephemeral
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs,file-cache:max-size-mb:-1"
    

    Substitua os seguintes valores:

    • NAMESPACE: o namespace do Kubernetes em que você quer implantar o pod.
    • KSA_NAME: o nome da conta de serviço do Kubernetes especificada ao configurar o acesso aos buckets do Cloud Storage.
    • BUCKET_NAME: o nome do bucket do Cloud Storage especificado ao configurar o acesso aos buckets do Cloud Storage. É possível especificar um sublinhado (_) para ativar todos os buckets que a conta de serviço do Kubernetes pode acessar. Para saber mais, consulte Montagem dinâmica na documentação do Cloud Storage FUSE.

      No manifesto de exemplo, o contêiner init data-loader gera 1.000 arquivos com 64 KiB e faz upload dos arquivos para um bucket do Cloud Storage. O contêiner principal data-validator lê todos os arquivos do bucket duas vezes e registra a duração.

  3. Execute o comando a seguir para aplicar o manifesto ao cluster:

    kubectl apply -f FILE_PATH
    

    Substitua FILE_PATH pelo caminho do arquivo YAML.

  4. Para ver a resposta, execute o seguinte comando:

    kubectl logs -n NAMESPACE gcs-fuse-csi-file-cache-example -c data-validator
    

    Substitua NAMESPACE pelo namespace da carga de trabalho.

    A saída será parecida com esta:

    first read with cache miss
    real    0m 54.68s
    ...
    second read from local cache
    real    0m 0.38s
    ...
    

    A saída mostra que a segunda leitura com cache local é muito mais rápida que a primeira leitura com uma ausência no cache.

Pod (download paralelo)

Para anexar o volume temporário de CSI com download paralelo em um pod, siga estas etapas:

  1. Crie um manifesto YAML de pod com a seguinte especificação:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-ephemeral 
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/ephemeral-storage-limit: "50Gi" 
    spec:
      containers:
      ...
      volumes:
      - name: gcs-fuse-csi-ephemeral 
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs,file-cache:enable-parallel-downloads:true,file-cache:max-size-mb:-1"
            fileCacheCapacity: "-1"
    

    Substitua os seguintes valores:

    • NAMESPACE: o namespace do Kubernetes em que você quer implantar o pod.
    • BUCKET_NAME: o nome do bucket do Cloud Storage especificado ao configurar o acesso aos buckets do Cloud Storage. É possível especificar um sublinhado (_) para ativar todos os buckets que a conta de serviço do Kubernetes pode acessar. Para saber mais, consulte Montagem dinâmica na documentação do Cloud Storage FUSE.
  2. Execute o comando a seguir para aplicar o manifesto ao cluster:

    kubectl apply -f FILE_PATH
    

    Substitua FILE_PATH pelo caminho do arquivo YAML.

Job

Para anexar o volume temporário de CSI em um job, siga estas etapas:

  1. Crie um manifesto YAML de job com a seguinte especificação:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: gcs-fuse-csi-job-example 
      namespace: NAMESPACE 
    spec:
      template:
        metadata: 
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          serviceAccountName: KSA_NAME 
          containers:
          - name: writer
            image: busybox
            command:
              - "/bin/sh"
              - "-c"
              - touch /data/test && echo $(date) >> /data/test && sleep 10
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
          - name: reader
            image: busybox
            command:
              - "/bin/sh"
              - "-c"
              - sleep 10 && cat /data/test 
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
              readOnly: true
          volumes:
          - name: gcs-fuse-csi-ephemeral
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: BUCKET_NAME
          restartPolicy: Never 
      backoffLimit: 1
    

    Substitua os seguintes valores:

    • NAMESPACE: o namespace do Kubernetes em que você implanta o pod.
    • KSA_NAME: o nome da conta de serviço do Kubernetes especificada ao configurar o acesso aos buckets do Cloud Storage.
    • BUCKET_NAME: o nome do bucket do Cloud Storage especificado ao configurar o acesso aos buckets do Cloud Storage. É possível especificar um sublinhado (_) para ativar todos os buckets que a conta de serviço do Kubernetes pode acessar. Para saber mais, consulte Montagem dinâmica na documentação do Cloud Storage FUSE.

    O manifesto de exemplo mostra estas configurações obrigatórias:

    • metadata.annotations: a anotação gke-gcsfuse/volumes: "true" é obrigatória. Consulte Configurar o contêiner secundário para anotações opcionais.
    • spec.volumes[n].csi.driver: use gcsfuse.csi.storage.gke.io como o nome do driver CSI.

    Opcionalmente, é possível ajustar estas variáveis:

    • spec.volumes[n].csi.volumeAttributes.mountOptions: transmita as opções de montagem para o Cloud Storage FUSE. Especifique as flags em uma string separada por vírgulas, sem espaços.
    • spec.volumes[n].csi.volumeAttributes: transmita outros atributos de volume para o Cloud Storage FUSE.
    • spec.volumes[n].csi.readOnly: especifique "true" se todas as montagens de volume forem somente leitura.
    • spec.containers[n].volumeMounts[m].readOnly: especifique "true" se apenas uma montagem de volume específica for somente leitura.
  2. Execute o comando a seguir para aplicar o manifesto ao cluster:

    kubectl apply -f FILE_PATH
    

    Substitua FILE_PATH pelo caminho do arquivo YAML.

Montar o mesmo bucket do Cloud Storage com diferentes volumes temporários de CSI

Opcionalmente, é possível usar vários volumes temporários de CSI com suporte do mesmo bucket do Cloud Storage. Para fazer isso, anexe dois ou mais volumes que referenciam o mesmo nome de bucket em caminhos de montagem diferentes. Um exemplo de caso de uso é a montagem de diferentes volumes temporários de CSI com diferentes opções de montagem no mesmo pod, em que cada volume temporário se refere ao mesmo bucket do Cloud Storage. Confira a seguir um exemplo de manifesto de pod usando esse recurso:

apiVersion: batch/v1
kind: Job
metadata:
  name: gcs-fuse-csi-job-example
  namespace: NAMESPACE
spec:
  template:
    metadata:
      annotations:
        gke-gcsfuse/volumes: "true"
    spec:
      serviceAccountName: KSA_NAME
      containers:
      - name: writer
        image: busybox
        command:
          - "/bin/sh"
          - "-c"
          - touch /data/test && echo $(date) >> /data/test && sleep 10
        volumeMounts: 
        - name: gcs-fuse-csi-ephemeral
          mountPath: /data
        volumeMounts:
        - name: gcs-fuse-csi-ephemeral-with-mo
          mountPath: /data2
      volumes:
      - name: gcs-fuse-csi-ephemeral
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: BUCKET_NAME
      - name: gcs-fuse-csi-ephemeral-with-mo
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs"
      restartPolicy: Never
  backoffLimit: 1

Resolver problemas

Para mais informações sobre como resolver problemas do driver CSI do Cloud Storage FUSE, consulte o guia de solução de problemas na documentação do projeto do GitHub.

A seguir