Instructivo de uso de Cloud Storage FUSE con Cloud Run


En este instructivo, se muestra cómo activar Cloud Storage como un sistema de archivos de red en un servicio de Cloud Run. Se puede usar el mismo enfoque para un trabajo de Cloud Run.

En el instructivo, se usa el adaptador de código abierto FUSE para compartir datos entre varios contenedores y servicios.

Para activar un sistema de archivos, el servicio debe usar el entorno de ejecución de segunda generación de Cloud Run. Los trabajos de Cloud Run usan el entorno de segunda generación automáticamente.

El entorno de ejecución de segunda generación permite que los sistemas de archivos de red se activen en un directorio en el contenedor. La activación de un sistema de archivos permite compartir recursos entre un sistema host y las instancias, y que los recursos se conserven después de que una instancia se recolecte de elementos no utilizados.

Usar un sistema de archivos de red con Cloud Run requiere conocimiento avanzado de Docker porque tu contenedor debe ejecutar varios procesos, incluidos el proceso de activación del sistema de archivos y la aplicación. En este instructivo, se explican los conceptos necesarios junto con un ejemplo funcional. Sin embargo, a medida que adaptas este instructivo a tu propia aplicación, asegúrate de comprender las implicaciones de cualquier cambio que puedas hacer.

Descripción general del diseño

filesystem-architecture

En el diagrama, se muestra el servicio de Cloud Run que se conecta al bucket de Cloud Storage a través del adaptador FUSE gcsfuse. El servicio de Cloud Run y el bucket de Cloud Storage se encuentran dentro de la misma región para quitar el costo de red y obtener el mejor rendimiento.

Limitaciones

  • En este instructivo, no se describe cómo elegir un sistema de archivos ni se trata la preparación para la producción. Revisa las diferencias clave de un sistema de archivos POSIX y otras semánticas de Cloud Storage FUSE.

  • En este instructivo, no se muestra cómo trabajar con un sistema de archivos ni analizar los patrones de acceso a los archivos.

Objetivos

  • Crear un bucket de Cloud Storage para que funcione como un recurso compartido de archivos

  • Compilar un Dockerfile con paquetes del sistema y también init-process para administrar los procesos de activación y de la aplicación.

  • Implementar en Cloud Run y verificar el acceso al sistema de archivos en el servicio

Costos

En este instructivo, se usan componentes facturables de Google Cloud, incluidos los siguientes:

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  4. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  5. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  6. Habilita las API de Cloud Run, Cloud Storage, Artifact Registry, and Cloud Build .

    Habilita las API

  7. Instala e inicializa la CLI de gcloud

Roles obligatorios

Para obtener los permisos que necesitas a fin de completar el instructivo con el conjunto mínimo de roles, pídele a tu administrador que te otorgue los siguientes roles de IAM en tu proyecto:

Si quieres obtener más información para otorgar roles, consulta Administra el acceso.

También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

Configura los valores predeterminados de gcloud

A fin de configurar gcloud con los valores predeterminados para el servicio de Cloud Run, sigue estos pasos:

  1. Configura el proyecto predeterminado:

    gcloud config set project PROJECT_ID

    Reemplaza PROJECT_ID por el nombre del proyecto que creaste para este instructivo.

  2. Configura gcloud en la región que elegiste:

    gcloud config set run/region REGION

    Reemplaza REGION por la región de Cloud Run compatible que prefieras.

Ubicaciones de Cloud Run

Cloud Run es regional, lo que significa que la infraestructura que ejecuta los servicios se ubica en una región específica, y Google la administra para que esté disponible de manera redundante en todas las zonas de esa región.

El cumplimiento de los requisitos de latencia, disponibilidad o durabilidad es el factor principal para seleccionar la región en la que se ejecutan los servicios de Cloud Run. Por lo general, puedes seleccionar la región más cercana a los usuarios, pero debes considerar la ubicación de los otros productos de Google Cloud que usa el servicio de Cloud Run. Si usas productos de Google Cloud en varias ubicaciones, la latencia y el costo del servicio pueden verse afectados.

Cloud Run está disponible en las siguientes regiones:

Sujetas a los Precios del nivel 1

  • asia-east1 (Taiwán)
  • asia-northeast1 (Tokio)
  • asia-northeast2 (Osaka)
  • europe-north1 (Finlandia)ícono de hoja Bajo nivel de CO2
  • europe-southwest1 (Madrid)
  • europe-west1 (Bélgica) ícono de hoja Bajo nivel de CO2
  • europe-west4 (Países Bajos)
  • europe-west8 (Milán)
  • europe-west9 (París) ícono de hoja Bajo nivel de CO2
  • me-west1 (Tel Aviv)
  • us-central1 (Iowa) ícono de hoja Bajo nivel de CO2
  • us-east1 (Carolina del Sur)
  • us-east4 (Virginia del Norte)
  • us-east5 (Columbus)
  • us-south1 (Dallas)
  • us-west1 (Oregón) ícono de hoja Bajo nivel de CO2

Sujetas a los Precios del nivel 2

  • asia-east2 (Hong Kong)
  • asia-northeast3 (Seúl, Corea del Sur)
  • asia-southeast1 (Singapur)
  • asia-southeast2 (Yakarta)
  • asia-south1 (Bombay, India)
  • asia-south2 Delhi (India)
  • australia-southeast1 (Sídney)
  • australia-southeast2 (Melbourne)
  • europe-central2 (Varsovia, Polonia)
  • europe-west10 (Berlín)
  • europe-west12 (Turín)
  • europe-west2 (Londres, Reino Unido) ícono de hoja Bajo nivel de CO2
  • europe-west3 (Fráncfort, Alemania) ícono de hoja Bajo nivel de CO2
  • europe-west6 (Zúrich, Suiza) ícono de hoja Bajo nivel de CO2
  • me-central1 (Doha)
  • me-central2 (Dammam)
  • northamerica-northeast1 (Montreal) ícono de hoja Bajo nivel de CO2
  • northamerica-northeast2 (Toronto) ícono de hoja Bajo nivel de CO2
  • southamerica-east1 (São Paulo, Brasil) ícono de hoja Bajo nivel de CO2
  • southamerica-west1 (Santiago, Chile) ícono de hoja Bajo nivel de CO2
  • us-west2 (Los Ángeles)
  • us-west3 (Salt Lake City)
  • us-west4 (Las Vegas)

Si ya creaste un servicio de Cloud Run, puedes ver la región en el panel de Cloud Run en la consola de Google Cloud.

Recupera la muestra de código

A fin de recuperar la muestra de código para su uso, haz lo siguiente:

  1. Clona el repositorio de la app de muestra en tu máquina local:

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    De manera opcional, puedes descargar la muestra como un archivo zip y extraerla.

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    De manera opcional, puedes descargar la muestra como un archivo ZIP y extraerla.

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    De manera opcional, puedes descargar la muestra como un archivo ZIP y extraerla.

  2. Ve al directorio que contiene el código de muestra de Cloud Run:

    Node.js

    cd nodejs-docs-samples/run/filesystem/

    Python

    cd python-docs-samples/run/filesystem/

    Java

    cd java-docs-samples/run/filesystem/

Comprende el código

Por lo general, debes ejecutar un solo proceso o aplicación dentro de un contenedor. Ejecutar un solo proceso por contenedor reduce la complejidad de administrar el ciclo de vida de varios procesos: administrar los reinicios, finalizar el contenedor si falla algún proceso y las responsabilidades del PID 1, como reenvío de señal y beneficios secundarios de zombis. Sin embargo, el uso de sistemas de archivos de red en Cloud Run requiere que uses contenedores de varios procesos para ejecutar el proceso de activación y la aplicación del sistema de archivos. En este instructivo, se muestra cómo finalizar el contenedor en caso de fallas en el proceso y administrar las responsabilidades del PID 1. El comando de activación tiene una funcionalidad integrada para controlar los reintentos.

Puedes usar un administrador de procesos para ejecutar y administrar varios procesos como el punto de entrada del contenedor. En este instructivo, se usa tini, un reemplazo de inicialización que limpia los procesos inertes y realiza el reenvío de señales. Específicamente, este proceso init permite que la señal SIGTERM en el cierre se propague a la aplicación. Se puede detectar la señal SIGTERM para obtener una finalización correcta de la aplicación. Obtén más información sobre el ciclo de vida de un contenedor en Cloud Run.

Define la configuración del entorno con el Dockerfile

Este servicio de Cloud Run requiere uno o más paquetes de sistema adicionales que no están disponibles de forma predeterminada. La instrucción RUN instalará tini como nuestro init-process y gcsfuse, el adaptador FUSE. Obtén más información para trabajar con paquetes del sistema en el servicio de Cloud Run en el instructivo Usa paquetes del sistema.

El siguiente conjunto de instrucciones creará un directorio de trabajo, copiará el código fuente e instalará las dependencias de la app.

ENTRYPOINT especifica el objeto binario init-process que se antepone a las instrucciones CMD, en este caso, es la secuencia de comandos de inicio. Esto inicia un único init-process y, luego, envía por proxy todas las señales recibidas a una sesión con permisos de administrador en ese proceso secundario.

Los conjuntos de instrucciones CMD establecen el comando que se ejecutará cuando se ejecute la imagen, la secuencia de comandos de inicio. También proporciona argumentos predeterminados para ENTRYPOINT. Comprende cómo interactúan CMD y ENTRYPOINT.

Node.js


# Use the official Node.js image.
# https://hub.docker.com/_/node
FROM node:20-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    curl \
    gnupg \
    lsb-release \
    tini && \
    gcsFuseRepo=gcsfuse-`lsb_release -c -s` && \
    echo "deb https://packages.cloud.google.com/apt $gcsFuseRepo main" | \
    tee /etc/apt/sources.list.d/gcsfuse.list && \
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
    apt-key add - && \
    apt-get update && \
    apt-get install -y gcsfuse && \
    apt-get clean

# Set fallback mount directory
ENV MNT_DIR /mnt/gcs

# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY package*.json ./

# Install production dependencies.
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

# Ensure the script is executable
RUN chmod +x /app/gcsfuse_run.sh

# Use tini to manage zombie processes and signal forwarding
# https://github.com/krallin/tini
ENTRYPOINT ["/usr/bin/tini", "--"]

# Pass the wrapper script as arguments to tini
CMD ["/app/gcsfuse_run.sh"]

Python

# Use the official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.11-buster

# Install system dependencies
RUN set -e; \
    apt-get update -y && apt-get install -y \
    tini \
    lsb-release; \
    gcsFuseRepo=gcsfuse-`lsb_release -c -s`; \
    echo "deb https://packages.cloud.google.com/apt $gcsFuseRepo main" | \
    tee /etc/apt/sources.list.d/gcsfuse.list; \
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
    apt-key add -; \
    apt-get update; \
    apt-get install -y gcsfuse \
    && apt-get clean

# Set fallback mount directory
ENV MNT_DIR /mnt/gcs

# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./

# Install production dependencies.
RUN pip install -r requirements.txt

# Ensure the script is executable
RUN chmod +x /app/gcsfuse_run.sh

# Use tini to manage zombie processes and signal forwarding
# https://github.com/krallin/tini
ENTRYPOINT ["/usr/bin/tini", "--"]

# Pass the startup script as arguments to Tini
CMD ["/app/gcsfuse_run.sh"]

Java

# Use the official maven/Java 11 image to create a build artifact.
# https://hub.docker.com/_/maven
FROM maven:3-eclipse-temurin-17-alpine as builder

# Copy local code to the container image.
WORKDIR /app
COPY pom.xml .
COPY src ./src

# Build a release artifact.
RUN mvn package -DskipTests

# Use Eclipse Temurin for base image.
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM eclipse-temurin:18-jdk-focal

# Install system dependencies
RUN set -e; \
    apt-get update -y && apt-get install -y \
    gnupg2 \
    tini \
    lsb-release; \
    gcsFuseRepo=gcsfuse-`lsb_release -c -s`; \
    echo "deb https://packages.cloud.google.com/apt $gcsFuseRepo main" | \
    tee /etc/apt/sources.list.d/gcsfuse.list; \
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
    apt-key add -; \
    apt-get update; \
    apt-get install -y gcsfuse && apt-get clean

# Set fallback mount directory
ENV MNT_DIR /mnt/gcs

# Copy the jar to the production image from the builder stage.
COPY --from=builder /app/target/filesystem-*.jar /filesystem.jar

# Copy the statup script
COPY gcsfuse_run.sh ./gcsfuse_run.sh
RUN chmod +x ./gcsfuse_run.sh

# Use tini to manage zombie processes and signal forwarding
# https://github.com/krallin/tini
ENTRYPOINT ["/usr/bin/tini", "--"]

# Run the web service on container startup.
CMD ["/gcsfuse_run.sh"]

Define tus procesos en la secuencia de comandos de inicio

La secuencia de comandos de inicio crea el directorio de punto de activación, en el que se podrá acceder al bucket de Cloud Storage. A continuación, la secuencia de comandos conecta el bucket de Cloud Storage con el punto de activación del servicio mediante el comando gcsfuse y, luego, inicia el servidor de la aplicación. El comando gcsfuse tiene una función de reintento integrada. Por lo que no se necesita ninguna secuencia de comandos Bash. Por último, el comando wait se usa para detectar procesos en segundo plano y salir de la secuencia de comandos.

Node.js

#!/usr/bin/env bash
set -eo pipefail

# Create mount directory for service
mkdir -p $MNT_DIR

echo "Mounting GCS Fuse."
gcsfuse --debug_gcs --debug_fuse $BUCKET $MNT_DIR
echo "Mounting completed."

# Start the application
node index.js &

# Exit immediately when one of the background processes terminate.
wait -n

Python

#!/usr/bin/env bash
set -eo pipefail

# Create mount directory for service
mkdir -p $MNT_DIR

echo "Mounting GCS Fuse."
gcsfuse --debug_gcs --debug_fuse $BUCKET $MNT_DIR
echo "Mounting completed."

# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
# Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance scaling.
exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

Java

#!/usr/bin/env bash
set -eo pipefail

# Create mount directory for service
mkdir -p $MNT_DIR

echo "Mounting GCS Fuse."
gcsfuse --debug_gcs --debug_fuse $BUCKET $MNT_DIR
echo "Mounting completed."

# Start the application
java -jar filesystem.jar

# Exit immediately when one of the background processes terminate.
wait -n

Trabaja con archivos

Node.js

Consulta index.js para interactuar con el sistema de archivos.

Python

Consulta main.py para interactuar con el sistema de archivos.

Java

Consulta FilesystemApplication.java para interactuar con el sistema de archivos.

Envía el servicio

  1. Crea un bucket de Cloud Storage o vuelve a usar un bucket existente:

    gsutil mb -l REGION gs://BUCKET_NAME
    

    Reemplaza BUCKET_NAME por el nombre del bucket de Cloud Storage, es decir, my-fuse-bucket. Los nombres de los buckets de Cloud Storage deben ser únicos a nivel global y están sujetos a los requisitos de nombres.

    Establece -l para especificar la ubicación de tu bucket. Por ejemplo, us-central1 A fin de obtener el mejor rendimiento y evitar los cargos de herramientas de redes interregionales, asegúrate de que el bucket de Cloud Storage se encuentre en la misma región que los servicios de Cloud Run que necesitan acceder a él.

  2. Crea una cuenta de servicio para que funcione como la identidad del servicio:

    gcloud iam service-accounts create fs-identity
  3. Otorga acceso a la cuenta de servicio al bucket de Cloud Storage:

    gcloud projects add-iam-policy-binding PROJECT_ID \
         --member "serviceAccount:fs-identity@PROJECT_ID.iam.gserviceaccount.com" \
         --role "roles/storage.objectAdmin"
    
  4. Para implementar desde la fuente, borra el Dockerfile adicional y cambia el nombre del Dockerfile del instructivo:

    rm Dockerfile
    cp gcsfuse.Dockerfile Dockerfile
    
  5. Compila e implementa la imagen de contenedor en Cloud Run:

    gcloud run deploy filesystem-app --source . \
        --execution-environment gen2 \
        --allow-unauthenticated \
        --service-account fs-identity \
        --update-env-vars BUCKET=BUCKET_NAME
    

    Este comando compila e implementa el servicio de Cloud Run y especifica el entorno de ejecución de segunda generación. La implementación desde la fuente compilará la imagen según el Dockerfile y la enviará al repositorio de Artifact Registry: cloud-run-source-deploy.

    Obtén más información sobre Implementa a partir del código fuente.

Depuración

Si la implementación no se realiza correctamente, consulta Cloud Logging para obtener más detalles.

Si deseas todos los registros del proceso de activación, se utilice la marca --foreground en combinación con el comando de activación en la secuencia de comandos de inicio, gcsfuse_run.sh:

  gcsfuse --foreground --debug_gcs --debug_fuse GCSFUSE_BUCKET MNT_DIRECTORY &
  

  • Agrega --debug_http para el resultado de la depuración de solicitud/respuesta HTTP.
  • Agrega --debug_fuse para habilitar el resultado de depuración relacionado con la fusión.
  • Agrega --debug_gcs para imprimir la información de sincronización y la solicitud de GCS.

Encuentra más sugerencias en la Guía de solución de problemas.

Prueba

Para probar el servicio completo, haz lo siguiente:

  1. Dirige tu navegador a la URL proporcionada en el paso de implementación anterior.
  2. Deberías ver un archivo recién creado en su bucket de Cloud Storage.
  3. Haz clic en el archivo para ver el contenido.

Si eliges seguir desarrollando estos servicios, recuerda que tienen acceso restringido de la administración de identidades y accesos (IAM) al resto de Google Cloud y necesitarán tener funciones de IAM adicionales para acceder a muchos otros servicios.

Análisis de costos

Los precios de Cloud Storage dependen en gran medida del almacenamiento de datos, la cantidad de datos que almacena la clase de almacenamiento, la ubicación de tus depósitos, el uso de red y la cantidad de datos que se leen o transfieren entre los buckets. Obtén más información sobre los Cargos generados con Cloud Storage FUSE.

Cloud Run se cobra por usurpación de recursos y se redondea a los 100 ms más cercana para la memoria, la CPU, la cantidad de solicitudes y las herramientas de redes. Por lo tanto, el costo variará según la configuración del servicio, la cantidad de solicitudes y el tiempo de ejecución.

Por ejemplo, 1 TiB de datos almacenados en un bucket de Standard Storage alojado en Iowa (us-central1) cuesta $0.02 por mes por GiB, que es alrededor de 1,024 GiB * $0.02 = $20.48. Esta estimación depende del servicio de Cloud Run y del bucket de Cloud Storage que se aloja en la misma región para evitar los costos de salida.

Visita las páginas de precios individuales para obtener los precios más actualizados o explora una estimación en la Calculadora de precios de Google Cloud.

Limpia

Si creaste un proyecto nuevo para este instructivo, bórralo. Si usaste un proyecto existente y deseas conservarlo sin los cambios que se agregaron en este instructivo, borra los recursos creados para el instructivo.

Borra el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, sigue estos pasos:

  1. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Borra los recursos del instructivo

  1. Usa este comando para borrar el servicio de Cloud Run que implementaste en este instructivo:

    gcloud run services delete SERVICE-NAME

    En el ejemplo anterior, SERVICE-NAME es el nombre del servicio que elegiste.

    También puedes borrar los servicios de Cloud Run desde la consola de Google Cloud.

  2. Quita la configuración de región predeterminada de gcloud que agregaste durante la configuración en el instructivo:

     gcloud config unset run/region
    
  3. Quita la configuración del proyecto:

     gcloud config unset project
    
  4. Borra otros recursos de Google Cloud que creaste en este instructivo:

¿Qué sigue?