1. Panoramica
Questa serie di codelab (tutorial pratici autogestiti) ha lo scopo di aiutare gli sviluppatori Java di Google App Engine (Standard) a modernizzare le loro app guidandoli attraverso una serie di migrazioni. Se segui questi passaggi, puoi aggiornare la tua app per renderla più portatile e decidere di inserirla in un container per Cloud Run, il servizio di hosting di container di Google Cloud gemello di App Engine, e altri servizi di hosting di container.
Questo tutorial ti insegna a containerizzare un'app App Engine per il deployment nel servizio completamente gestito Cloud Run con un Dockerfile. I Dockerfile sono il metodo di deployment più pratico per questa migrazione, ma offrono anche il maggior numero di opzioni per personalizzare il processo di build.
Oltre a insegnarti i passaggi necessari per passare da App Engine a Cloud Run, imparerai anche ad eseguire l'upgrade di un'app App Engine Java 8 a Java 17.
Se l'applicazione di cui ti interessa eseguire la migrazione utilizza molto i servizi in bundle legacy di App Engine o altre funzionalità specifiche di App Engine, la guida Accesso ai servizi in bundle di App Engine per Java 11/17 potrebbe essere un punto di partenza migliore rispetto a questo codelab.
Imparerai a utilizzare
- Utilizza Cloud Shell
- Abilita le API Cloud Run, Artifact Registry e Cloud Build
- Containerizza l'app utilizzando Docker, Docker e Cloud Build
- Esegui il deployment delle immagini container in Cloud Run
Che cosa ti serve
- Un progetto Google Cloud con un account di fatturazione Google Cloud attivo e App Engine abilitato.
- Conoscenza pratica dei comandi Linux più comuni
- Conoscenza di base dello sviluppo e del deployment di app App Engine
- Un'app servlet Java 8 di cui vuoi eseguire la migrazione a Java 17 ed eseguire il deployment in Cloud Run (può trattarsi di un'app su App Engine o solo dell'origine)
Sondaggio
Come utilizzerai questo tutorial?
Come valuteresti la tua esperienza con Java?
Come valuti la tua esperienza di utilizzo dei servizi Google Cloud?
2. Sfondo
I sistemi PaaS come App Engine e Cloud Functions offrono molti vantaggi per il tuo team e la tua applicazione, ad esempio consentono agli amministratori di sistema e ai team DevOps di concentrarsi sulla creazione di soluzioni. Con le piattaforme serverless, la tua app può scalare automaticamente in base alle esigenze, ridursi a zero con la fatturazione pay-per-use per controllare i costi e utilizzare una serie di linguaggi di sviluppo comuni.
Tuttavia, anche la flessibilità dei container è interessante. Grazie alla possibilità di scegliere qualsiasi linguaggio, libreria e programma binario, i container offrono il meglio di entrambi i mondi: la praticità del serverless e la flessibilità dei container. Questo è lo scopo di Google Cloud Run.
L'apprendimento dell'utilizzo di Cloud Run non rientra nell'ambito di questo codelab, ma è trattato nella documentazione di Cloud Run. L'obiettivo è acquisire familiarità con la containerizzazione dell'app App Engine per Cloud Run (o altri servizi ospitati in container). Prima di procedere, devi sapere alcune cose, in particolare che la tua esperienza utente sarà leggermente diversa.
In questo codelab imparerai a creare e distribuire container. Scoprirai come containerizzare la tua app con un Dockerfile, eseguire la migrazione dalla configurazione di App Engine e (facoltativamente) definire i passaggi di build per Cloud Build. Ciò comporterà l'abbandono di alcune funzionalità specifiche di App Engine. Se preferisci non seguire questo percorso, puoi comunque eseguire l'upgrade a un runtime Java 11/17 mantenendo le tue app su App Engine.
3. Configurazione/preparazione
1. Configura il progetto
Per questo tutorial, utilizzerai un'app di esempio dal repository appengine-java-migration-samples in un progetto nuovo di zecca. Assicurati che il progetto abbia un account di fatturazione attivo.
Se intendi spostare un'app App Engine esistente su Cloud Run, puoi utilizzare questa app per seguire la procedura.
Esegui questo comando per abilitare le API necessarie per il tuo progetto:
gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com
2. Ottieni l'app di esempio di base
Clona l'app di esempio sul tuo computer o su Cloud Shell, quindi vai alla cartella baseline.
L'esempio è un'app Datastore basata su servlet Java 8 destinata al deployment su App Engine. Segui le istruzioni nel file README su come preparare questa app per il deployment di App Engine.
3. (Facoltativo) Esegui il deployment dell'app di base
Quanto segue è necessario solo se vuoi verificare che l'app funzioni su App Engine prima di eseguire la migrazione a Cloud Run.
Fai riferimento ai passaggi descritti in README.md:
- Installare/riprendere confidenza con la CLI
gcloud - Inizializza gcloud CLI per il tuo progetto con
gcloud init - Crea il progetto App Engine con
gcloud app create - Esegui il deployment dell'app di esempio su App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
- Verifica che l'app venga eseguita su App Engine senza problemi
4. Crea un repository Artifact Registry
Dopo aver containerizzato l'app, avrai bisogno di uno spazio in cui eseguire il push e archiviare le immagini. Il modo consigliato per procedere su Google Cloud è con Artifact Registry.
Crea il repository denominato migration con gcloud nel seguente modo:
gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"
Tieni presente che questo repository utilizza il tipo di formato docker, ma sono disponibili diversi tipi di repository.
A questo punto, hai l'app App Engine di base e il tuo progetto Google Cloud è pronto per la migrazione a Cloud Run.
4. Modificare i file dell'applicazione
Nei casi in cui la tua app utilizza molto i servizi integrati legacy, la configurazione o altre funzionalità solo di App Engine, ti consigliamo di continuare ad accedere a questi servizi durante l'upgrade al nuovo runtime. Questo codelab mostra un percorso di migrazione per le applicazioni che utilizzano già servizi autonomi o che possono essere sottoposte a refactoring in modo fattibile per farlo.
1. Upgrade a Java 17
Se la tua app è su Java 8, valuta l'upgrade a una versione LTS successiva come 11 o 17 per rimanere al passo con gli aggiornamenti di sicurezza e accedere a nuove funzionalità del linguaggio.
Inizia aggiornando le proprietà in pom.xml in modo da includere quanto segue:
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
In questo modo, la versione del progetto verrà impostata su 17, il plug-in del compilatore verrà informato che vuoi accedere alle funzionalità del linguaggio Java 17 e che le classi compilate devono essere compatibili con la JVM Java 17.
2. Includere un server web
Esistono diverse differenze tra App Engine e Cloud Run da prendere in considerazione quando si passa da uno all'altro. Una differenza è che mentre il runtime Java 8 di App Engine forniva e gestiva un server Jetty per le app che ospitava, Cloud Run non lo fa. Utilizzeremo Spring Boot per fornire un server web e un contenitore di servlet.
Aggiungi le seguenti dipendenze:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.6</version>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<version>2.6.6</version>
</dependency>
<!-- ... -->
</dependencies>
Spring Boot incorpora un server Tomcat per impostazione predefinita, ma questo esempio escluderà questo artefatto e utilizzerà Jetty per ridurre al minimo le differenze nel comportamento predefinito dopo la migrazione.
3. Configurazione di Spring Boot
Anche se Spring Boot sarà in grado di riutilizzare le servlet senza modifiche, sarà necessaria una configurazione per assicurarsi che siano rilevabili.
Crea la seguente classe MigratedServletApplication.java nel pacchetto com.example.appengine:
package com.example.appengine;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
@EnableAutoConfiguration
public class MigratedServletApplication {
public static void main(String[] args) {
SpringApplication.run(MigratedServletApplication.class, args);
}
}
Tieni presente che questo include l'annotazione @ServletComponentScan, che cercherà (nel pacchetto corrente per impostazione predefinita) qualsiasi @WebServlets e li renderà disponibili come previsto.
4. Pacchettizzazione dell'app come file JAR
Sebbene sia possibile inserire la tua app in un container a partire da un file WAR, l'operazione diventa più semplice se la pacchettizzi come JAR eseguibile. Non sarà necessaria molta configurazione, in particolare per i progetti che utilizzano Maven come strumento di compilazione, poiché il packaging jar è il comportamento predefinito.
Rimuovi il tag packaging nel file pom.xml:
<packaging>war</packaging>
Poi, aggiungi spring-boot-maven-plugin:
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.6</version>
</plugin>
<!-- ... -->
</plugins>
5. Migrazione dalla configurazione, dai servizi e dalle dipendenze di App Engine
Come accennato all'inizio del codelab, Cloud Run e App Engine sono progettati per offrire esperienze utente diverse. Alcune funzionalità offerte da App Engine pronte all'uso, come i servizi Cron e Task Queue, devono essere ricreate manualmente e verranno trattate in dettaglio nei moduli successivi.
L'app di esempio non utilizza i servizi in bundle legacy, ma gli utenti le cui app lo fanno possono consultare le seguenti guide:
- Migrazione dai servizi in bundle per trovare servizi autonomi adatti.
- Migrazione dei file di configurazione XML a YAML, per gli utenti che eseguono la migrazione ai runtime Java 11/17 rimanendo su App Engine.
Poiché d'ora in poi eseguirai il deployment in Cloud Run, puoi rimuovere appengine-maven-plugin:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- can be set w/ -DprojectId=myProjectId on command line -->
<projectId>${app.projectId}</projectId>
<!-- set the GAE version or use "GCLOUD_CONFIG" for an autogenerated GAE version -->
<version>GCLOUD_CONFIG</version>
</configuration>
</plugin>
5. Containerizza applicazione
A questo punto, puoi indicare a Cloud Build come creare il container dell'applicazione. Con questo metodo di containerizzazione non è necessario un file di configurazione della build separato (cloudbuild.yaml). Possiamo semplicemente definire un Dockerfile minimo come punto di partenza:
FROM eclipse-temurin
ARG JAR_FILE=JAR_FILE_MUST_BE_SPECIFIED_AS_BUILD_ARG
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar","/app.jar"]
Questo Dockerfile raggruppa la versione uber-jar del servizio Spring Boot in un unico livello. È l'approccio più semplice alla containerizzazione di Dockerfile, ma presenta una serie di svantaggi, soprattutto se si confrontano tempi ripetuti in cui le dipendenze sono relativamente stabili. Preoccupazioni come questa sono il motivo per cui questo metodo di containerizzazione è considerato più avanzato. Il vantaggio è che la scrittura del tuo Dockerfile ti offre il controllo completo sull'immagine di base e l'accesso ai vantaggi in termini di prestazioni della scrittura di un'immagine a più livelli.
2**. Esegui il processo di compilazione**
Ora che hai comunicato a Cloud Build i passaggi di build desiderati, puoi eseguire il deployment con un solo clic.
Esegui questo comando:
gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME
Sostituisci i valori dei segnaposto nel comando precedente con quanto segue:
- LOCATION: la località regionale o multiregionale del repository.
- PROJECT_ID: l'ID del tuo progetto Cloud.
- REPOSITORY: il nome del tuo repository Artifact Registry.
- IMAGE_NAME: il nome dell'immagine container.
Al termine del processo, l'immagine container è stata creata, archiviata in Artifact Registry ed eseguita il deployment in Cloud Run.
Al termine di questo codelab, la tua app dovrebbe essere uguale a quella nella cartella mod4-migrate-to-cloud-run.
Ecco fatto! Hai eseguito la migrazione di un'app Java 8 App Engine a Java 17 e Cloud Run e ora hai una comprensione più chiara del lavoro necessario per cambiare e scegliere tra le opzioni di hosting.
6. Riepilogo/Pulizia
Congratulazioni, hai eseguito l'upgrade, la containerizzazione e la migrazione della tua app, concludendo questo tutorial.
Da qui, il passaggio successivo è scoprire di più sulle funzionalità di sicurezza CI/CD e della catena di fornitura del software che sono a portata di mano ora che puoi eseguire il deployment con Cloud Build:
- Creazione di passaggi di build personalizzati con Cloud Build
- Creazione e gestione dei trigger di build
- Utilizzo della scansione on demand nella pipeline di Cloud Build
(Facoltativo) Esegui la pulizia e/o disattiva il servizio
Se hai eseguito il deployment dell'app di esempio su App Engine durante questo tutorial, ricordati di disabilitare l'app per evitare addebiti. Quando vuoi passare al codelab successivo, puoi riattivarlo. Mentre le app App Engine sono disattivate, non ricevono traffico e non generano addebiti. Tuttavia, l'utilizzo di Datastore potrebbe essere fatturabile se supera la quota senza costi, quindi elimina una quantità sufficiente di dati per rientrare in questo limite.
D'altra parte, se non intendi continuare con le migrazioni e vuoi eliminare tutto completamente, puoi eliminare il servizio o arrestare completamente il progetto.
7. Risorse aggiuntive
Problemi/feedback relativi ai codelab del modulo di migrazione di App Engine
Se riscontri problemi con questo codelab, cerca prima il tuo problema prima di presentare una segnalazione. Link per cercare e creare nuovi problemi:
Risorse per la migrazione
- Opzioni di migrazione per separare i servizi App Engine
- Configurazione dei trigger di build per Cloud Build
- Maggiori informazioni sulla migrazione a Java 11/17
Risorse online
Di seguito sono riportate risorse online che potrebbero essere pertinenti per questo tutorial:
App Engine
- Documentazione di App Engine
- Informazioni su prezzi e quote di App Engine
- Confronto tra piattaforme di prima e seconda generazione
- Supporto a lungo termine per i runtime legacy
Altre informazioni sul cloud
- Livello "Sempre senza costi" di Google Cloud
- Google Cloud CLI (
gcloudCLI) - Tutta la documentazione di Google Cloud
Video
- Serverless Migration Station
- Serverless Expeditions
- Iscriviti a Google Cloud Tech
- Iscriviti a Google Developers
Licenza
Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.