Montar segmentos de Cloud Storage como volúmenes efímeros de CSI

En esta guía se explica cómo usar volúmenes efímeros de CSI respaldados por tus cubos de Cloud Storage para gestionar automáticamente los recursos de almacenamiento de tus pods o trabajos de Kubernetes en Google Kubernetes Engine (GKE). Los volúmenes efímeros de CSI están vinculados al ciclo de vida del pod o del trabajo, y no es necesario que gestiones manualmente los objetos PersistentVolume y PersistentVolumeClaim.

Esta guía está dirigida a los administradores y operadores de plataformas que quieren simplificar la gestión del almacenamiento de sus aplicaciones de GKE.

Antes de leer esta página, asegúrate de que conoces los volúmenes efímeros de CSI, los pods y los trabajos de Kubernetes, y los segmentos de Cloud Storage.

Si ya conoces los PersistentVolumes y quieres que sean coherentes con las implementaciones que ya tienes y que dependen de este tipo de recurso, consulta Montar los buckets de Cloud Storage como volúmenes persistentes.

Antes de empezar

Asegúrate de que has completado estos requisitos previos:

Cómo funciona el almacenamiento efímero de CSI para los segmentos de Cloud Storage

Los volúmenes efímeros de CSI simplifican la gestión del almacenamiento de tus aplicaciones en GKE. Puedes definir volúmenes efímeros de CSI directamente en la especificación de tu pod o trabajo. Al usar volúmenes efímeros de CSI, no es necesario tener objetos PersistentVolume y PersistentVolumeClaim independientes.

Para usar un volumen efímero de CSI, debes realizar las siguientes operaciones:

  1. Definición del almacenamiento: especifica el almacenamiento en el archivo YAML de tu pod o trabajo, incluido el controlador CSI que se va a usar y los parámetros necesarios. En el caso del controlador CSI de FUSE de Cloud Storage, debe especificar el nombre del segmento y otros detalles relevantes.

    Si quieres, puedes optimizar el rendimiento de tu controlador de CSI mediante la función almacenamiento en caché de archivos. El almacenamiento en caché de archivos puede mejorar el rendimiento de las aplicaciones de GKE almacenando en caché los archivos de Cloud Storage a los que se accede con frecuencia en un disco más rápido.

    Además, puedes usar la función de descarga paralela para acelerar la lectura de archivos de gran tamaño de Cloud Storage en descargas multiproceso. Puedes usar esta función para mejorar los tiempos de carga de los modelos, sobre todo en lecturas de más de 1 GB.

  2. Invocación del controlador: cuando creas el pod o el trabajo, GKE detecta la solicitud de volumen efímero y llama al controlador de CSI de FUSE de Cloud Storage.

  3. Montaje y adjunto de volumen: el controlador de CSI monta el volumen efímero de CSI (que apunta al bucket de Cloud Storage subyacente) y lo pone a disposición del pod o del trabajo, lo que permite que tu aplicación acceda a él. Para ajustar cómo se montan los contenedores en el sistema de archivos, puedes usar opciones de montaje. También puedes usar atributos de volumen para configurar el comportamiento específico del controlador CSI de Cloud Storage FUSE.

  4. Gestión del ciclo de vida: el volumen efímero existe durante el ciclo de vida del pod o del trabajo. Cuando se elimina el pod o se completa el trabajo, el controlador CSI gestiona automáticamente la limpieza y desmonta el volumen.

Adjuntar el volumen efímero de CSI

Sigue estas instrucciones en función de si quieres adjuntar el volumen efímero de CSI a un pod o a un trabajo.

Pod

Para adjuntar el volumen efímero de CSI en un pod, sigue estos pasos:

  1. Crea un manifiesto YAML de Pod con las siguientes especificaciones:

    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" 
    

    Sustituye los siguientes valores:

    • NAMESPACE: el espacio de nombres de Kubernetes en el que quieres desplegar tu pod.
    • KSA_NAME: el nombre de la cuenta de servicio de Kubernetes que especificaste al configurar el acceso a los segmentos de Cloud Storage.
    • BUCKET_NAME: el nombre del segmento de Cloud Storage que especificó al configurar el acceso a los segmentos de Cloud Storage. Puedes especificar un guion bajo (_) para montar todos los contenedores a los que pueda acceder la cuenta de servicio de Kubernetes. Para obtener más información, consulta Montaje dinámico en la documentación de Cloud Storage FUSE.

    En el archivo de manifiesto de ejemplo se muestran estos ajustes obligatorios:

    • metadata.annotations: es obligatorio incluir la anotación gke-gcsfuse/volumes: "true". Consulta Configurar el contenedor sidecar para ver las anotaciones opcionales.
    • spec.volumes[n].csi.driver: usa gcsfuse.csi.storage.gke.io como nombre del controlador de CSI.

    También puedes ajustar estas variables:

    • spec.terminationGracePeriodSeconds: de forma predeterminada, este valor es 30. Si necesitas escribir archivos grandes en el segmento de Cloud Storage, aumenta este valor para asegurarte de que Cloud Storage FUSE tenga tiempo suficiente para vaciar los datos después de que se cierre tu aplicación. Para obtener más información, consulta Prácticas recomendadas de Kubernetes: finalización con gracia.
    • spec.volumes[n].csi.volumeAttributes.mountOptions: pasa opciones de montaje a Cloud Storage FUSE. Especifica las marcas en una cadena separada por comas, sin espacios.
    • spec.volumes[n].csi.volumeAttributes: pasa atributos de volumen adicionales a Cloud Storage FUSE.
    • spec.volumes[n].csi.readOnly: especifica el valor true si todos los montajes de volumen son de solo lectura.
    • spec.containers[n].volumeMounts[m].readOnly: especifica "true" si solo se puede leer un montaje de volumen específico.
  2. Ejecuta el siguiente comando para aplicar el manifiesto a tu clúster:

    kubectl apply -f FILE_PATH
    

    Sustituye FILE_PATH por la ruta a tu archivo YAML.

Pod (almacenamiento en caché de archivos)

Para adjuntar el volumen efímero de CSI con almacenamiento en caché de archivos en un pod, sigue estos pasos:

  1. Crea un clúster o un grupo de nodos con almacenamiento efímero con copia de seguridad en SSD local siguiendo los pasos que se indican en el artículo Crear un clúster o un grupo de nodos con almacenamiento efímero con copia de seguridad en SSD local.

  2. Crea un manifiesto YAML de Pod con las siguientes especificaciones:

    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"
    

    Sustituye los siguientes valores:

    • NAMESPACE: el espacio de nombres de Kubernetes en el que quieres desplegar tu pod.
    • KSA_NAME: el nombre de la cuenta de servicio de Kubernetes que especificaste al configurar el acceso a los segmentos de Cloud Storage.
    • BUCKET_NAME: el nombre del segmento de Cloud Storage que especificó al configurar el acceso a los segmentos de Cloud Storage. Puedes especificar un guion bajo (_) para montar todos los contenedores a los que pueda acceder la cuenta de servicio de Kubernetes. Para obtener más información, consulta Montaje dinámico en la documentación de Cloud Storage FUSE.

      En el manifiesto de ejemplo, el contenedor init data-loader genera 1000 archivos de 64 KiB y los sube a un segmento de Cloud Storage. El contenedor principal data-validator lee todos los archivos del bucket dos veces y registra la duración.

  3. Ejecuta el siguiente comando para aplicar el manifiesto a tu clúster:

    kubectl apply -f FILE_PATH
    

    Sustituye FILE_PATH por la ruta a tu archivo YAML.

  4. Para ver el resultado del registro, ejecuta el siguiente comando:

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

    Sustituye NAMESPACE por el espacio de nombres de tu carga de trabajo.

    La salida debería ser similar a la siguiente:

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

    El resultado muestra que la segunda lectura con la caché local es mucho más rápida que la primera lectura con un fallo de caché.

Pod (descarga paralela)

Para adjuntar el volumen efímero de CSI con descarga paralela en un pod, sigue estos pasos:

  1. Crea un manifiesto YAML de Pod con las siguientes especificaciones:

    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"
    

    Sustituye los siguientes valores:

    • NAMESPACE: el espacio de nombres de Kubernetes en el que quieres desplegar tu pod.
    • BUCKET_NAME: el nombre del segmento de Cloud Storage que especificó al configurar el acceso a los segmentos de Cloud Storage. Puedes especificar un guion bajo (_) para montar todos los contenedores a los que pueda acceder la cuenta de servicio de Kubernetes. Para obtener más información, consulta Montaje dinámico en la documentación de Cloud Storage FUSE.
  2. Ejecuta el siguiente comando para aplicar el manifiesto a tu clúster:

    kubectl apply -f FILE_PATH
    

    Sustituye FILE_PATH por la ruta a tu archivo YAML.

Tarea

Para adjuntar el volumen efímero de CSI en un trabajo, sigue estos pasos:

  1. Crea un manifiesto YAML de Job con la siguiente especificación:

    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
    

    Sustituye los siguientes valores:

    • NAMESPACE: el espacio de nombres de Kubernetes en el que despliega su pod.
    • KSA_NAME: el nombre de la cuenta de servicio de Kubernetes que especificaste al configurar el acceso a los segmentos de Cloud Storage.
    • BUCKET_NAME: el nombre del segmento de Cloud Storage que especificó al configurar el acceso a los segmentos de Cloud Storage. Puedes especificar un guion bajo (_) para montar todos los contenedores a los que pueda acceder la cuenta de servicio de Kubernetes. Para obtener más información, consulta Montaje dinámico en la documentación de Cloud Storage FUSE.

    En el archivo de manifiesto de ejemplo se muestran estos ajustes obligatorios:

    • metadata.annotations: es obligatorio incluir la anotación gke-gcsfuse/volumes: "true". Consulta Configurar el contenedor sidecar para ver las anotaciones opcionales.
    • spec.volumes[n].csi.driver: usa gcsfuse.csi.storage.gke.io como nombre del controlador de CSI.

    También puedes ajustar estas variables:

    • spec.volumes[n].csi.volumeAttributes.mountOptions: pasa opciones de montaje a Cloud Storage FUSE. Especifica las marcas en una cadena separada por comas, sin espacios.
    • spec.volumes[n].csi.volumeAttributes: pasa atributos de volumen adicionales a Cloud Storage FUSE.
    • spec.volumes[n].csi.readOnly: especifica "true" si todos los volúmenes montados son de solo lectura.
    • spec.containers[n].volumeMounts[m].readOnly: especifica true si solo se puede leer un montaje de volumen específico.
  2. Ejecuta el siguiente comando para aplicar el manifiesto a tu clúster:

    kubectl apply -f FILE_PATH
    

    Sustituye FILE_PATH por la ruta a tu archivo YAML.

Solucionar problemas

Para obtener más información sobre cómo solucionar problemas con el controlador CSI de Cloud Storage FUSE, consulta la guía de solución de problemas en la documentación del proyecto de GitHub.

Siguientes pasos