Questo tutorial descrive come eseguire la migrazione delle app web Node.js in esecuzione su Heroku a Cloud Run su Cloud de Confiance by S3NS. Questo tutorial è rivolto ad architetti e product owner che vogliono eseguire la migrazione delle proprie app da Heroku ai servizi gestiti su Cloud de Confiance.
Cloud Run è una piattaforma di computing gestita che consente di eseguire container stateless richiamabili tramite richieste HTTP. È basato su Knative open source, che consente la portabilità tra piattaforme e supporta i flussi di lavoro e gli standard dei container per la distribuzione continua. La piattaforma Cloud Run è ben integrata con la suite di prodotti Cloud de Confiance e semplifica la progettazione e lo sviluppo di app portatili, scalabili e resilienti.
In questo tutorial imparerai a eseguire la migrazione di un'app a Cloud de Confiance scritta in Node.js e che utilizza Heroku Postgres come servizio di supporto su Heroku. L'app web è containerizzata e ospitata in Cloud Run e utilizza Cloud SQL per PostgreSQL come livello di persistenza.
Nel tutorial utilizzerai un'app semplice chiamata Tasks che ti consente di visualizzare e creare attività. Queste attività sono archiviate in Heroku Postgres nell'attuale deployment dell'app su Heroku.
Questo tutorial presuppone che tu abbia familiarità con le funzionalità di base di Heroku e che tu abbia un account Heroku (o l'accesso a un account). Si presume inoltre che tu abbia familiarità con Cloud Run, Cloud SQL, Docker e Node.js.
Obiettivi
- Creare un'immagine Docker per eseguire il deployment dell'app in Cloud Run.
- Crea un'istanza Cloud SQL per PostgreSQL da utilizzare come backend dopo la migrazione a Cloud de Confiance.
- Esamina il codice Node.js per capire in che modo Cloud Run si connette a Cloud SQL e per vedere le modifiche al codice (se presenti) necessarie per eseguire la migrazione a Cloud Run da Heroku.
- Esegui la migrazione dei dati da Heroku Postgres a Cloud SQL per PostgreSQL.
- Esegui il deployment dell'app in Cloud Run.
- Testa l'app di cui hai eseguito il deployment.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Cloud de Confiance by S3NS:
Potrebbero esserti addebitati anche i costi per le risorse che utilizzi su Heroku.
Prima di iniziare
-
In the Cloud de Confiance console, on the project selector page, select or create a Cloud de Confiance project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Cloud de Confiance project.
Enable the Cloud SQL, Cloud Build, Cloud Run, Container Registry, Service Networking, Serverless VPC Access APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Make sure that you have the following role or roles on the project: Cloud Run > Cloud Run Admin, Cloud Storage > Storage Admin, Cloud SQL > Cloud SQL Admin, Compute Engine > Compute Network Admin, Resource Manager > Project IAM Admin, Cloud Build > Cloud Build Editor, Serverless VPC Access > Serverless VPC Access Admin, Logging > Logs Viewer, Service Accounts > Service Account Admin, Service Accounts > Service Account User, and Service Usage > Service Usage Consumer
Check for the roles
-
In the Cloud de Confiance console, go to the IAM page.
Go to IAM - Select the project.
-
In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.
- For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.
Grant the roles
-
In the Cloud de Confiance console, go to the IAM page.
Go to IAM - Select the project.
- Click Grant access.
-
In the New principals field, enter your user identifier. This is typically the identifier for a user in a workforce identity pool. For details, see Represent workforce pool users in IAM policies, or contact your administrator.
- Click Select a role, then search for the role.
- To grant additional roles, click Add another role and add each additional role.
- Click Save.
-
Configura l'ambiente
Apri Cloud Shell.
In Cloud Shell, imposta le variabili di ambiente e i valori predefiniti per Google Cloud CLI utilizzata in questo tutorial.
gcloud config set project PROJECT_ID gcloud config set run/region us-central1
Sostituisci
PROJECT_IDcon l'ID progetto.
Architettura
Le figure seguenti mostrano l'architettura dell'app web su Heroku (così com'è) e il suo layout architetturale su Cloud de Confiance (che creerai).
L'app Tasks attualmente di cui è stato eseguito il deployment in Heroku è composta da uno o più dyno web. I dyno web sono in grado di ricevere e rispondere al traffico HTTP, a differenza dei dyno worker, che sono più adatti per i job in background e le attività programmate. L'app pubblica una pagina indice che mostra le attività archiviate in un database Postgres, utilizzando la libreria di modelli Mustache per Node.js.
Puoi accedere all'app tramite un URL HTTPS. Una route /tasks in quell'URL ti consente di creare nuove attività.
In Cloud de Confiance, Cloud Run viene utilizzato come piattaforma serverless per il deployment dell'app Tasks. Cloud Run è progettato per eseguire container stateless basati su richieste. È ideale quando hai bisogno che il tuo servizio gestito supporti app containerizzate che scalano automaticamente e anche fino a zero quando non gestiscono traffico.
Mappa i componenti utilizzati in Heroku in Cloud de Confiance
La tabella seguente mappa i componenti della piattaforma Heroku su Cloud de Confiance. Questa mappatura ti aiuta a tradurre l'architettura descritta in questo tutorial da Heroku a Cloud de Confiance.
| Componente | Piattaforma Heroku | Cloud de Confiance |
|---|---|---|
| Container | Dynos: Heroku utilizza il modello di container per creare e scalare le app Heroku. Questi container Linux sono chiamati dyno e possono essere scalati fino a un numero specificato da te per supportare le richieste di risorse per la tua app Heroku. Puoi scegliere tra una gamma di tipi di dyno in base ai requisiti di memoria e CPU della tua app. | Container Cloud Run: Cloud de Confiance supporta l'esecuzione di workload containerizzati in container stateless che possono essere eseguiti in un ambiente completamente gestito o in cluster Google Kubernetes Engine (GKE). |
| App web | App Heroku: i dyno sono i componenti di base delle app Heroku. Le app sono generalmente costituite da uno o più tipi di dyno, di solito una combinazione di dyno web e worker. | Servizio Cloud Run: un'app web può essere modellata come servizio Cloud Run. Ogni servizio riceve il proprio endpoint HTTPS e può fare lo scale up o lo scale down automatico da 0 a N in base al traffico verso l'endpoint del servizio. |
| Database | Heroku Postgres è il database as a service (DaaS) di Heroku basato su PostgreSQL. | Cloud SQL è un servizio di database gestito per i database relazionali su Cloud de Confiance. |
Esegui il deployment dell'app web Tasks di esempio su Heroku
Le sezioni successive mostrano come configurare l'interfaccia a riga di comando (CLI) per Heroku, clonare il repository di codice sorgente GitHub ed eseguire il deployment dell'app su Heroku.
Configura l'interfaccia a riga di comando per Heroku
Questo tutorial esegue l'interfaccia a riga di comando di Heroku in Cloud Shell e deve eseguire l'autenticazione utilizzando una chiave API Heroku. Quando viene eseguita in Cloud Shell, l'interfaccia a riga di comando di Heroku non può eseguire l'autenticazione utilizzando una password o un'autenticazione basata sul web.
In alternativa, se esegui l'esempio su un terminale locale, puoi utilizzare qualsiasi metodo di autenticazione dell'interfaccia a riga di comando di Heroku. Quando esegui il tutorial su un terminale locale, devi anche installare Google Cloud CLI, git e Docker.
Accedi alla console web di Heroku, quindi, dalla pagina delle impostazioni dell'account, copia il valore della chiave API.
In Cloud Shell, installa l'interfaccia a riga di comando di Heroku
In Cloud Shell, autentica l'interfaccia a riga di comando di Heroku. Quando ti viene chiesta la password, inserisci il valore della chiave API che hai copiato dalla console Heroku, non la password che utilizzi per accedere alla console.
heroku login --interactive
clona il repository del codice sorgente
In Cloud Shell, clona il repository GitHub dell'app Tasks di esempio:
git clone https://github.com/GoogleCloudPlatform/migrate-webapp-heroku-to-cloudrun-node.git
Passa alla directory creata clonando il repository:
cd migrate-webapp-heroku-to-cloudrun-node
La directory contiene i seguenti file:
- Uno script Node.js denominato
index.jscon il codice per le route gestite dall'app web. - I file
package.jsonepackage-lock.jsonche delineano le dipendenze dell'app web. Devi installare queste dipendenze per eseguire l'app. - Un file
Procfileche specifica il comando eseguito dall'app all'avvio. Crea un fileProcfileper eseguire il deployment della tua app su Heroku. - Una directory
views, con i contenuti HTML pubblicati dall'app web nel percorso "/". - Un file
.gitignore.
- Uno script Node.js denominato
Esegui il deployment di un'app su Heroku
In Cloud Shell, crea un'app Heroku:
heroku create
Prendi nota del nome creato per l'app. Questo valore ti servirà nel passaggio successivo.
Crea una variabile di ambiente per il nome dell'app Heroku:
export APP_NAME=APP_NAME
Sostituisci
APP_NAMEcon il nome dell'app restituito dal comandoheroku create.Aggiungi il componente aggiuntivo Heroku Postgres per eseguire il provisioning di un database PostgreSQL:
heroku addons:create heroku-postgresql:mini
Assicurati che il componente aggiuntivo sia stato aggiunto correttamente:
heroku addons
Se il componente aggiuntivo Postgres è stato aggiunto correttamente, viene visualizzato un messaggio simile al seguente:
Add-on Plan Price State ----------------- ----- -------- ----- heroku-postgresql mini 5$/month created
Esegui il deployment dell'app su Heroku:
git push heroku master
Esegui questo comando per confermare il valore di DATABASE_URL.
heroku config
Prendi nota del valore recuperato per DATABASE_URL. Questo valore ti servirà nel passaggio successivo.
Eseguire un container Docker.
docker run -it --rm postgres psql "DATABASE_URL"
Sostituisci
DATABASE_URLcon l'URL di Heroku Postgres che hai annotato nel passaggio precedente.Nel container Docker, crea la tabella
TASKSutilizzando il seguente comando:CREATE TABLE TASKS (DESCRIPTION TEXT NOT NULL);
Esci dal container:
exitIn Cloud Shell, ottieni l'URL web della tua app Heroku eseguendo questo comando:
heroku info
Apri l'URL web in una finestra del browser. L'app ha l'aspetto dello screenshot seguente (anche se la tua versione non avrà le attività elencate):
Crea attività di esempio nella tua app dal browser. Assicurati che le attività vengano recuperate dal database e siano visibili nell'interfaccia utente.
Prepara il codice dell'app web per la migrazione a Cloud Run
Questa sezione descrive i passaggi da completare per preparare l'app web per il deployment in Cloud Run.
Crea e pubblica il tuo container Docker in Container Registry
Per creare il container dell'app in modo che possa essere eseguito in Cloud Run, è necessaria un'immagine Docker. Puoi creare il container manualmente o utilizzando Buildpacks.
Crea il container manualmente
In Cloud Shell, crea un Dockerfile nella directory creata clonando il repository per questo tutorial:
cat <<"EOF" > Dockerfile # Use the official Node image. # https://hub.docker.com/_/node FROM node:10-alpine # Create and change to the app directory. WORKDIR /app # Copying this separately prevents re-running npm install on every code change. COPY package*.json ./ RUN npm install # Copy local code to the container image. COPY . /app # Configure and document the service HTTP port. ENV PORT 8080 EXPOSE $PORT # Run the web service on container startup. CMD ["npm", "start"] EOF
Crea il container con Cloud Build e pubblica l'immagine in Container Registry:
gcloud builds submit --tag gcr.io/PROJECT_ID/APP_NAME:1 \ --gcs-log-dir=gs://PROJECT_ID_cloudbuild
Crea una variabile di ambiente per contenere il nome dell'immagine Docker che hai creato:
export IMAGE_NAME="gcr.io/PROJECT_ID/APP_NAME:1"
Crea un container con Buildpacks
In Cloud Shell, installa l'interfaccia a riga di comando pack.
Imposta l'interfaccia a riga di comando pack in modo che utilizzi il builder Heroku per impostazione predefinita:
pack config default-builder heroku/buildpacks:22
Crea una variabile di ambiente per contenere il nome dell'immagine Docker:
export IMAGE_NAME=gcr.io/PROJECT_ID/APP_NAME:1
Crea l'immagine utilizzando il comando
packed eseguine il push o pubblicala in Container Registry:pack build --publish $IMAGE_NAME
Crea un'istanza Cloud SQL per PostgreSQL
Crea un'istanza Cloud SQL per PostgreSQL che funga da backend per l'app web. In questo tutorial, PostgreSQL è più adatto come app di esempio di cui è stato eseguito il deployment su Heroku, che utilizza un database Postgres come backend. Ai fini di questa app, la migrazione a Cloud SQL per PostgreSQL da un servizio Postgres gestito non richiede modifiche allo schema.
Prepara la tua rete per Cloud SQL con un indirizzo IP privato.
gcloud compute addresses create google-managed-services-default \ --global \ --purpose=VPC_PEERING \ --prefix-length=16 \ --description="peering range for CloudSQL Private Service Access" \ --network=default gcloud services vpc-peerings connect \ --service=servicenetworking.googleapis.com \ --ranges=google-managed-services-default \ --network=default \ --project=PROJECT_ID
Crea una variabile di ambiente denominata
CLOUDSQL_DB_NAMEper contenere il nome dell'istanza di database che creerai nel passaggio successivo:export CLOUDSQL_DB_NAME=tasks-db
Crea il database:
gcloud sql instances create $CLOUDSQL_DB_NAME \ --cpu=1 \ --memory=4352Mib \ --database-version=POSTGRES_15 \ --region=us-central1 \ --network default \ --no-assign-ip
L'inizializzazione dell'istanza potrebbe richiedere alcuni minuti.
Imposta una password per l'utente Postgres:
gcloud sql users set-password postgres \ --instance=$CLOUDSQL_DB_NAME \ --password=POSTGRES_PASSWORDSostituisci
POSTGRES_PASSWORDcon la password che vuoi utilizzare per il database Postgres.
Importa i dati in Cloud SQL da Heroku Postgres
Esistono diversi pattern di migrazione che puoi utilizzare per eseguire la migrazione dei dati in Cloud SQL. In genere, l'approccio migliore che richiede tempi di inattività minimi o nulli è configurare Cloud SQL come replica del database di cui viene eseguita la migrazione e impostare Cloud SQL come istanza principale dopo la migrazione. Heroku Postgres non supporta le repliche esterne (follower), quindi in questo tutorial utilizzerai strumenti open source per eseguire la migrazione dello schema dell'app.
Per l'app Tasks in questo tutorial, utilizzi l'utilità pg_dump per esportare i dati da Heroku Postgres in un bucket Cloud Storage e poi importarli in Cloud SQL. Questa utilità può trasferire i dati tra versioni omogenee o quando la versione del database di destinazione è più recente di quella del database di origine.
In Cloud Shell, recupera le credenziali del database Heroku Postgres collegato all'app di esempio. Ti serviranno nel passaggio successivo.
heroku pg:credentials:url
Questo comando restituisce la stringa delle informazioni di connessione e l'URL di connessione per la tua applicazione. La stringa delle informazioni di connessione ha il seguente formato:
"dbname=DATABASE_NAME host=FQDN port=5432 user=USER_NAME password=PASSWORD_STRING sslmode=require"
Nel passaggio successivo, avrai bisogno dei valori mostrati nella stringa di connessione.
Per un esempio di un valore FQDN (nome di dominio completo) in una stringa di informazioni di connessione, consulta la documentazione di Heroku.
Imposta le variabili di ambiente in modo che contengano i valori Heroku che utilizzi nei passaggi successivi:
export HEROKU_PG_DBNAME=DATABASE_NAME export HEROKU_PG_HOST=FQDN export HEROKU_PG_USER=USER_NAME export HEROKU_PG_PASSWORD=PASSWORD_STRING
Sostituisci quanto segue:
DATABASE_NAME: il nome del database mostrato nella stringa di informazioni.FQDN: il FQDN mostrato nella stringa informativa.USER_NAME: il nome utente mostrato nella stringa di informazioni.PASSWORD_STRING: la stringa della password mostrata nella stringa di informazioni.
Crea un backup in formato SQL del tuo database Heroku Postgres:
docker run \ -it --rm \ -e PGPASSWORD=$HEROKU_PG_PASSWORD \ -v $(pwd):/tmp \ --entrypoint "pg_dump" \ postgres \ -Fp \ --no-acl \ --no-owner \ -h $HEROKU_PG_HOST \ -U $HEROKU_PG_USER \ $HEROKU_PG_DBNAME > herokudump.sql
Crea una variabile di ambiente per contenere il nome del tuo bucket Cloud Storage:
export PG_BACKUP_BUCKET=gs://PROJECT_ID-pg-backup-bucket
Crea un bucket Cloud Storage:
gcloud storage buckets create $PG_BACKUP_BUCKET \ --location=us-central1 \ --public-access-prevention \ --uniform-bucket-level-access
Carica il file SQL in questo bucket:
gcloud storage cp herokudump.sql $PG_BACKUP_BUCKET/herokudump.sql
Autorizza l'istanza Cloud SQL con i ruoli necessari per importare il file SQL dal bucket Cloud Storage:
gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='get("serviceAccountEmailAddress")') \ --role=roles/storage.objectAdmin gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='get("serviceAccountEmailAddress")') \ --role=roles/cloudsql.editorImporta il file SQL nell'istanza Cloud SQL:
gcloud sql import sql $CLOUDSQL_DB_NAME $PG_BACKUP_BUCKET/herokudump.sql \ --database=postgres \ --user=postgres
Quando è richiesto
do you want to continue (y/n), inserisci "y".
In che modo Cloud Run accede al database Cloud SQL
Proprio come l'app web di cui è stato eseguito il deployment su Heroku deve connettersi all'istanza gestita di Heroku Postgres, Cloud Run richiede l'accesso a Cloud SQL per poter leggere e scrivere dati.
Cloud Run comunica con Cloud SQL utilizzando il proxy Cloud SQL, che viene attivato e configurato automaticamente quando esegui il deployment del container in Cloud Run. Il database non deve avere indirizzi IP esterni approvati perché tutte le comunicazioni che riceve provengono dal proxy che utilizza TCP sicuro.
Il codice deve richiamare le operazioni del database (ad esempio il recupero dei dati dal database o la scrittura nel database) richiamando il proxy su un socket UNIX.
Poiché questa app web è scritta in Node.js, utilizzi la libreria pg-connection-string per analizzare un URL del database e creare un oggetto config. Il vantaggio di questo approccio è che semplifica la connessione al database di backend su Heroku e Cloud Run.
Nel passaggio successivo, passerai l'URL del database come variabile di ambiente quando esegui il deployment dell'app web.
Esegui il deployment dell'app di esempio in Cloud Run
In Cloud Shell, configura l'accesso VPC serverless per consentire il traffico privato da Cloud Run a Cloud SQL:
gcloud compute networks subnets create serverless-connector-subnet \ --network=default \ --range=10.0.0.0/28 \ --region=us-central1 gcloud compute networks vpc-access connectors create serverless-connector \ --region=us-central1 \ --subnet=serverless-connector-subnet
In Cloud Shell, crea una variabile di ambiente che contiene il nome della connessione dell'istanza Cloud SQL che hai creato:
export DB_CONN_NAME=$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='value(connectionName)')
Crea una variabile di ambiente denominata
DATABASE_URLper contenere la stringa di connessione per connetterti al proxy Cloud SQL tramite una porta UNIX.export DATABASE_URL="socket:/cloudsql/${DB_CONN_NAME}?db=postgres&user=postgres&password=POSTGRES_PASSWORD"Crea un account di servizio per Cloud Run con un ruolo IAM per connetterti al database:
gcloud iam service-accounts create sa-run-db-client gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:sa-run-db-client@PROJECT_ID.s3ns.iam.gserviceaccount.com \ --role=roles/cloudsql.clientEsegui il deployment dell'app web in Cloud Run:
gcloud run deploy tasksapp-PROJECT_ID \ --image=$IMAGE_NAME \ --service-account=sa-run-db-client@PROJECT_ID.s3ns.iam.gserviceaccount.com \ --set-env-vars=DATABASE_URL=$DATABASE_URL \ --add-cloudsql-instances $DB_CONN_NAME \ --vpc-connector serverless-connector \ --allow-unauthenticatedIl comando precedente collega anche il container Cloud Run all'istanza di database Cloud SQL che hai creato. Il comando imposta una variabile di ambiente per Cloud Run in modo che punti alla stringa
DATABASE_URLcreata nel passaggio precedente.
testa l'applicazione
In Cloud Shell, recupera l'URL in cui Cloud Run gestisce il traffico:
gcloud run services list
Puoi anche esaminare il servizio Cloud Run nella consoleCloud de Confiance .
Assicurati che l'app web accetti le richieste HTTP accedendo all'URL del servizio Cloud Run.
Cloud Run crea, o avvia, un nuovo container quando viene inviata una richiesta HTTP all'endpoint di pubblicazione e se un container non è già in esecuzione. Ciò significa che la richiesta che causa l'avvio di un nuovo container potrebbe richiedere un po' più di tempo per essere gestita. Considerando questo tempo aggiuntivo, tieni conto del numero di richieste in parallelo che la tua app può supportare e di eventuali requisiti di memoria specifici che potrebbe avere.
Per questa app, utilizza le impostazioni di contemporaneità predefinite, che consentono a un servizio Cloud Run di gestire 80 richieste contemporaneamente da un singolo container.
Esegui la pulizia
Per evitare che al tuo account Cloud de Confiance vengano addebitati costi relativi alle risorse utilizzate in questo tutorial: Puoi anche eliminare le risorse create in Heroku per questo tutorial.
Elimina il progetto Cloud de Confiance
- Nella console Cloud de Confiance , vai alla pagina Gestisci risorse.
- Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
- Nella finestra di dialogo, digita l'ID progetto, quindi fai clic su Chiudi per eliminare il progetto.
Elimina l'app Heroku
Per eliminare l'app di esempio di cui hai eseguito il deployment in Heroku e il componente aggiuntivo PostgreSQL associato, esegui questo comando:
heroku apps:destroy -a APP_NAME
Passaggi successivi
- Scopri di più sull'importazione di dati in Cloud SQL.
- Esplora la documentazione di Cloud Run.