Tutorial sull'utilizzo di Filestore con Cloud Run


Questo tutorial mostra come montare Filestore come file system di rete su un servizio Cloud Run per condividere dati tra più container e servizi. Questo tutorial utilizza l'ambiente di esecuzione di seconda generazione di Cloud Run.

L'ambiente di esecuzione di seconda generazione consente di montare file system di rete in una directory all'interno di un container. Il montaggio di un file system consente la condivisione delle risorse tra un sistema host e le istanze e la persistenza delle risorse dopo la garbage collection di un'istanza.

L'utilizzo di un file system di rete con Cloud Run richiede conoscenze avanzate di Docker perché il container deve eseguire più processi, tra cui il montaggio del file system e il processo dell'applicazione. Questo tutorial spiega i concetti necessari insieme a un esempio pratico. Tuttavia, quando adatti questo tutorial alla tua applicazione, assicurati di comprendere le implicazioni di eventuali modifiche che potresti apportare.

Panoramica del design

L'istanza Filestore è ospitata all'interno di una rete Virtual Private Cloud (VPC). Le risorse all'interno di una rete VPC utilizzano un intervallo di indirizzi IP privati per comunicare con le API e i servizi Google; pertanto, per accedere ai file archiviati nell'istanza, i client devono trovarsi sulla stessa rete dell'istanza Filestore. Per la connessione del servizio Cloud Run alla rete VPC per comunicare con Filestore, è necessario un connettore di accesso VPC serverless. Scopri di più sull'accesso VPC serverless.

architettura-filesystem

Il diagramma mostra il servizio Cloud Run che si connette all'istanza Filestore tramite un connettore di accesso VPC serverless. L'istanza e il connettore Filestore si trovano all'interno della stessa rete VPC "predefinita" e nella stessa regione/zona del servizio Cloud Run per ottenere le migliori prestazioni.

Limitazioni

  • Questo tutorial non descrive come scegliere un file system o requisiti pronti per la produzione. Scopri di più su Filestore e sui livelli di servizio disponibili.

  • Questo tutorial non mostra come lavorare con un file system o come discutere dei pattern di accesso ai file.

Obiettivi

  • Crea un'istanza Filestore sulla rete VPC predefinita da utilizzare come condivisione file.

  • Crea un connettore di accesso VPC serverless sulla stessa rete VPC predefinita per connetterti al servizio Cloud Run.

  • Crea un Dockerfile con pacchetti di sistema e init-process per gestire i processi di montaggio e applicazione.

  • Eseguire il deployment in Cloud Run e verificare l'accesso al file system nel servizio.

Costi

Questo tutorial utilizza i componenti fatturabili di Google Cloud, tra cui:

Prima di iniziare

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Le autorizzazioni IAM controllano solo l'accesso alle operazioni di Filestore, come la creazione di un'istanza Filestore. Per controllare l'accesso alle operazioni sulla condivisione di file, come lettura o esecuzione, utilizza le autorizzazioni dei file POSIX. Scopri di più sul controllo dell'accesso.
  7. Enable the Cloud Run, Filestore, Serverless VPC Access, Artifact Registry, and Cloud Build APIs.

    Enable the APIs

  8. Installa e inizializza gcloud CLI.
  9. Aggiorna Google Cloud CLI: gcloud components update

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per completare il tutorial, chiedi all'amministratore di concederti i seguenti ruoli IAM sul tuo progetto:

Per saperne di più sulla concessione dei ruoli, consulta Gestire l'accesso.

Potresti anche essere in grado di ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Configurazione delle impostazioni predefinite di gcloud

Per configurare gcloud con i valori predefiniti per il tuo servizio Cloud Run:

  1. Imposta il progetto predefinito:

    gcloud config set project PROJECT_ID

    Sostituisci PROJECT_ID con il nome del progetto che hai creato per questo tutorial.

  2. Configura gcloud per la regione scelta:

    gcloud config set run/region REGION

    Sostituisci REGION con un'area geografica Cloud Run supportata a tua scelta.

  3. Configura gcloud per Filestore:

    gcloud config set filestore/zone ZONE
    

    Sostituisci ZONE con la zona di Filestore supportata a tua scelta.

Recupero dell'esempio di codice

Per recuperare l'esempio di codice da utilizzare:

  1. Clona il repository dell'app di esempio sulla tua macchina locale:

    Node.js

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

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    Python

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

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    Java

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

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

  2. Passa alla directory che contiene il codice di esempio di Cloud Run:

    Node.js

    cd nodejs-docs-samples/run/filesystem/

    Python

    cd python-docs-samples/run/filesystem/

    Java

    cd java-docs-samples/run/filesystem/

Nozioni di base sul codice

Normalmente, devi eseguire un singolo processo o un'applicazione all'interno di un container. L'esecuzione di un singolo processo per container riduce la complessità della gestione del ciclo di vita di più processi: gestione dei riavvii, arresto del container in caso di esito negativo del processo e responsabilità del PID 1 come l'inoltro degli indicatori e la raccolta di bambini zombie. Tuttavia, l'uso di file system di rete in Cloud Run richiede l'uso di container multi-processi per eseguire sia il processo di montaggio del file system sia l'applicazione. Questo tutorial mostra come terminare il container in caso di errore del processo e gestire le responsabilità del PID 1. Il comando mount ha una funzionalità integrata per gestire i nuovi tentativi.

Puoi utilizzare un gestore di processi per eseguire e gestire più processi come punto di ingresso del container. Questo tutorial utilizza tini, una sostituzione init che ripulisce i processi zombie ed esegue l'inoltro degli indicatori. In particolare, questo processo di inizializzazione consente al segnale SIGTERM allo arresto di propagarsi all'applicazione. Il segnale SIGTERM può essere rilevato per la terminazione controllata dell'applicazione. Scopri di più sul ciclo di vita di un container su Cloud Run.

Definizione della configurazione dell'ambiente con il Dockerfile

Questo servizio Cloud Run richiede uno o più pacchetti di sistema aggiuntivi non disponibili per impostazione predefinita. L'istruzione RUN installerà tini come nostro processo init e nfs-common, il che fornisce una funzionalità client NFS minima. Scopri di più sull'utilizzo dei pacchetti di sistema nel servizio Cloud Run nel tutorial per l'utilizzo dei pacchetti di sistema.

Il successivo insieme di istruzioni crea una directory di lavoro, copia il codice sorgente e installa le dipendenze dell'app.

ENTRYPOINT specifica il programma binario init-process che antepone alle istruzioni CMD. In questo caso, è lo script di avvio. Questo avvia un singolo processo tini e quindi indirizza tutti gli indicatori ricevuti a una sessione collegata a quel processo figlio.

L'istruzione CMD imposta il comando da eseguire durante l'esecuzione dell'immagine, ovvero lo script di avvio. Fornisce inoltre argomenti predefiniti per ENTRYPOINT. Scopri come interagiscono CMD e 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 -y && apt-get install -y \
    tini \
    nfs-common \
	libtool \
    && apt-get clean

# Set fallback mount directory
ENV MNT_DIR /mnt/nfs/filestore

# 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/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/run.sh"]

Python

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

# Install system dependencies
RUN apt-get update -y && apt-get install -y \
    tini \
    nfs-common \
    && apt-get clean

# Set fallback mount directory
ENV MNT_DIR /mnt/nfs/filestore

# 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/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/run.sh"]

Java


# Use the official maven 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 filesystem dependencies
RUN apt-get update -y && apt-get install -y \
    tini \
    nfs-kernel-server \
    nfs-common \
    && apt-get clean

# Set fallback mount directory
ENV MNT_DIR /mnt/nfs/filestore

# 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 run.sh ./run.sh
RUN chmod +x ./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 ["/run.sh"]

Definizione dei processi nello script di avvio

Lo script di avvio crea una directory che sarà il punto di montaggio, in cui sarà resa accessibile l'istanza Filestore. Successivamente, lo script utilizza il comando mount per collegare l'istanza Filestore, specificando l'indirizzo IP dell'istanza e il nome della condivisione file, al punto di montaggio del servizio, quindi avvia il server delle applicazioni. Il comando mount dispone di una funzionalità incorporata per riprovare; pertanto, non sono necessari ulteriori script bash. Infine, il comando wait viene utilizzato per rimanere in ascolto dei processi in background per uscire e quindi chiudere lo script.

Node.js

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

# Create mount directory for service.
mkdir -p $MNT_DIR

echo "Mounting Cloud Filestore."
mount -o nolock $FILESTORE_IP_ADDRESS:/$FILE_SHARE_NAME $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 Cloud Filestore."
mount -o nolock $FILESTORE_IP_ADDRESS:/$FILE_SHARE_NAME $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 Cloud Filestore."
mount -o nolock $FILESTORE_IP_ADDRESS:/$FILE_SHARE_NAME $MNT_DIR
echo "Mounting completed."

# Start the application
java -jar filesystem.jar

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

Lavorare con i file

Node.js

Per informazioni sull'interazione con il file system, vedi index.js.

Python

Vedi main.py per interagire con il file system.

Java

Vedi FilesystemApplication.java per informazioni sull'interazione con il file system.

Spedizione del servizio

  1. Crea un'istanza di Filestore:

    gcloud filestore instances create INSTANCE_ID \
        --tier=basic-hdd \
        --file-share=name=FILE_SHARE_NAME,capacity=1TiB \
        --network=name="default"
    

    Sostituisci INSTANCE_ID con il nome dell'istanza Filestore, ovvero my-filestore-instance, e FILE_SHARE_NAME con il nome della directory fornita dall'istanza Filestore, ad esempio vol1. Consulta gli articoli Denominazione dell'istanza e Denominazione della condivisione file.

    Per accedere ai file archiviati nell'istanza, i client (servizio Cloud Run) devono trovarsi sulla stessa rete dell'istanza Filestore. Questo comando crea l'istanza nella rete VPC predefinita e assegna un intervallo di indirizzi IP libero. I nuovi progetti iniziano con una rete predefinita e molto probabilmente non è necessario creare una rete separata.

    Scopri di più sulla configurazione delle istanze, consulta Creazione di istanze.

  2. Configura un connettore di accesso VPC serverless:

    Per connettersi all'istanza Filestore, il servizio Cloud Run deve accedere alla rete VPC autorizzata dell'istanza Filestore.

    Ogni connettore VPC richiede una propria subnet /28 in cui inserire le istanze del connettore. Questo intervallo IP non deve sovrapporsi ad alcuna prenotazione di indirizzi IP esistenti nella tua rete VPC. Ad esempio, 10.8.0.0 (/28) funzionerà nella maggior parte dei nuovi progetti oppure puoi" specificare un altro intervallo IP personalizzato inutilizzato, come 10.9.0.0 (/28). Puoi vedere quali intervalli IP sono attualmente prenotati nella console Google Cloud.

    gcloud compute networks vpc-access connectors create CONNECTOR_NAME \
      --region REGION \
      --range "10.8.0.0/28"
    

    Sostituisci CONNECTOR_NAME con il nome del connettore.

    Questo comando crea un connettore nella rete VPC predefinita, uguale all'istanza Filestore, con dimensioni della macchina e2-micro. Aumenta le dimensioni della macchina del connettore per migliorare la velocità effettiva del connettore, ma anche i costi. Inoltre, il connettore deve trovarsi nella stessa regione del servizio Cloud Run. Scopri di più sulla configurazione dell'accesso VPC serverless.

  3. Definisci una variabile di ambiente con l'indirizzo IP per l'istanza Filestore:

    export FILESTORE_IP_ADDRESS=$(gcloud filestore instances describe INSTANCE_ID --format "value(networks.ipAddresses[0])")
    
  4. Crea un account di servizio da utilizzare come identità di servizio. Per impostazione predefinita, non sono previsti privilegi oltre all'appartenenza al progetto.

    gcloud iam service-accounts create fs-identity

    Questo servizio non deve interagire con nessun altro elemento in Google Cloud, pertanto non è necessario assegnare autorizzazioni aggiuntive a questo account di servizio.

  5. Crea ed esegui il deployment dell'immagine container in Cloud Run:

    gcloud run deploy filesystem-app --source . \
        --vpc-connector CONNECTOR_NAME \
        --execution-environment gen2 \
        --allow-unauthenticated \
        --service-account fs-identity \
        --update-env-vars FILESTORE_IP_ADDRESS=$FILESTORE_IP_ADDRESS,FILE_SHARE_NAME=FILE_SHARE_NAME
    

    Questo comando crea ed esegue il deployment del servizio Cloud Run e specifica il connettore VPC e l'ambiente di esecuzione di seconda generazione. Il deployment dall'origine creerà l'immagine in base al Dockerfile ed eseguirà il push dell'immagine nel repository Artifact Registry: cloud-run-source-deploy.

    Scopri di più sul deployment da codice sorgente.

Debug

Se il deployment non va a buon fine, controlla Cloud Logging per ulteriori dettagli.

  • Se si verifica il timeout della connessione, assicurati di fornire l'indirizzo IP corretto dell'istanza Filestore.

  • Se l'accesso è stato negato dal server, verifica che il nome della condivisione file sia corretto.

  • Per tutti i log del processo di montaggio, utilizza il flag --verbose in combinazione con il comando mount: mount --verbose -o nolock $FILESTORE_IP_ADDRESS:/$FILE_SHARE_NAME $MNT_DIR

Provalo

Per provare il servizio completo:

  1. Vai nel browser all'URL fornito nel passaggio di deployment riportato sopra.
  2. Nell'istanza Filestore dovresti vedere un file appena creato.
  3. Fai clic sul file per visualizzarne i contenuti.

Se scegli di continuare a sviluppare questi servizi, ricorda che questi hanno un accesso limitato di Identity and Access Management (IAM) al resto di Google Cloud e che dovranno disporre di ruoli IAM aggiuntivi per accedere a molti altri servizi.

Discussione sui costi

Esempio di suddivisione dei costi per un servizio ospitato in Iowa (us-central1) con un'istanza Filestore da 1 TiB e un connettore di accesso VPC serverless. Visita le singole pagine dei prezzi per conoscere i prezzi più aggiornati.

Prodotto Costo al mese
Filestore (non dipende dalla quantità utilizzata) Costo = capacità sottoposta a provisioning (1024 GiB o 1 TiB) * Prezzo livello regionale (us-central1)

Livello HDD base: 1024 GiB * 0,16 $/mese = 163,84 $
A livello di zona (SSD): 1024 GiB * 0,25 $/mese = 256Ss00 $/0,00 $
Enterprise
Accesso VPC serverless Costo = prezzo per dimensione della macchina * numero di istanze (l'impostazione predefinita per le istanze minime è 2)

f1-micro: 3,88 $ * 2 istanze = 7,76 $
e2-micro: 6,11 $ * 2 istanze = 12,22 $
e2-standard-4: 97,83 $ * 2 istanze = 195,66 $
Cloud Run Costo = CPU + memoria + richieste + networking
Totale 163,84 $ + 12,22 $= 176,06 $/mese + costo di Cloud Run

Questo tutorial utilizza un'istanza Filestore di livello HDD di base. Il livello di servizio di un'istanza Filestore è una combinazione del tipo di istanza e del tipo di archiviazione. È possibile eseguire l'upgrade del tipo di istanza per aumentare la capacità e la scalabilità. È possibile eseguire l'upgrade del tipo di spazio di archiviazione per migliorare le prestazioni. Scopri di più sui consigli sui tipi di spazio di archiviazione. Anche la regione e la capacità influiscono sui prezzi di Filestore. Ad esempio, un'istanza TiB HDD di livello 1 di base in Iowa (us-central1) costa 0,16 $per GiB al mese, ovvero circa 163,84 $al mese.

I prezzi del connettore di accesso VPC serverless si basano sulle dimensioni e sul numero dell'istanza, nonché sul traffico in uscita dalla rete. Aumentando le dimensioni e il numero puoi migliorare la velocità effettiva o ridurre la latenza dei messaggi. Esistono 3 dimensioni di macchine: f1-micro, e2-micro ed e2-standard-4. Il numero minimo di istanze è 2, pertanto il costo minimo è il doppio del costo di quella dimensione della macchina.

I prezzi di Cloud Run si basano sull'utilizzo delle risorse, arrotondato ai 100 ms più vicini, per memoria, CPU, numero di richieste e networking. Pertanto il costo varierà in base alle impostazioni del servizio, al numero di richieste e al tempo di esecuzione. Questo servizio costerebbe un minimo di $176,06 al mese. Visualizza ed esplora una stima nel Calcolatore prezzi di Google Cloud.

Esegui la pulizia

Se hai creato un nuovo progetto per questo tutorial, elimina il progetto. Se hai utilizzato un progetto esistente e vuoi conservarlo senza le modifiche aggiunte in questo tutorial, elimina le risorse create per il tutorial.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione è eliminare il progetto che hai creato per il tutorial.

Per eliminare il progetto:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Eliminazione delle risorse del tutorial

  1. Elimina il servizio Cloud Run di cui hai eseguito il deployment in questo tutorial:

    gcloud run services delete SERVICE-NAME

    Dove SERVICE-NAME è il nome del servizio che hai scelto.

    Puoi anche eliminare i servizi Cloud Run dalla console Google Cloud.

  2. Rimuovi la configurazione della regione predefinita di gcloud aggiunta durante la configurazione del tutorial:

     gcloud config unset run/region
    
  3. Rimuovi la configurazione del progetto:

     gcloud config unset project
    
  4. Elimina le altre risorse Google Cloud create in questo tutorial:

Passaggi successivi