1. Descripción general
Esta serie de codelabs (instructivos de autoaprendizaje prácticos) tiene como objetivo ayudar a los desarrolladores de Java de Google App Engine (estándar) a modernizar sus apps guiándolos a través de una serie de migraciones. Si sigues estos pasos, puedes actualizar tu app para que sea más portátil y decidir alojarla en contenedores para Cloud Run, el servicio de alojamiento de contenedores de Google Cloud en App Engine y otros servicios de alojamiento de contenedores.
En este instructivo, aprenderás a organizar una app de App Engine en contenedores para implementarla en el servicio completamente administrado de Cloud Run con Jib. Con Jib, puedes crear imágenes de Docker, una plataforma conocida en la industria para desarrollar, enviar y ejecutar aplicaciones en contenedores.
Además de enseñarte los pasos necesarios para pasar de App Engine a Cloud Run, también aprenderás a actualizar una app de App Engine de Java 8 a Java 17.
Si tu aplicación usa mucho los servicios agrupados heredados de App Engine o alguna otra función de App Engine, te recomendamos que migres esos servicios o que los reemplaces antes de pasar a Cloud Run. Si necesitas más tiempo para investigar tus opciones de migración o deseas seguir usando los servicios en paquetes heredados por el momento, puedes acceder a los servicios en paquetes de App Engine para Java 11/17 cuando actualices a un entorno de ejecución más reciente. Cuando tu app sea más portátil, vuelve a este codelab para aprender a aplicar las instrucciones.
En un próximo lab,
- Usa Cloud Shell.
- Habilita las APIs de Cloud Run, Artifact Registry y Cloud Build
- Aloja tu app en contenedores con Jib y Cloud Build
- Implementa tus imágenes de contenedor en Cloud Run
Requisitos
- Un proyecto de Google Cloud Platform con una cuenta de facturación activa de GCP y App Engine habilitado
- Conocimiento práctico de los comandos comunes de Linux
- Conocimientos básicos sobre el desarrollo y la implementación de apps de App Engine
- Una app de servlet de Java 8 que quieras migrar a Java 17 y, luego, implementar en Cloud Run (puede ser una app en App Engine o solo la fuente)
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia con Java?
¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?
2. Segundo plano
Los sistemas de plataforma como servicio (PaaS), como App Engine y Cloud Functions, ofrecen muchas comodidades para tu equipo y aplicación, como permitir que los administradores de sistemas y los desarrolladores se enfoquen en la compilación de soluciones. Con las plataformas sin servidores, tu app puede realizar un ajuste de escala automático según sea necesario, reducir la escala verticalmente a cero con la facturación de pago por uso que ayuda a controlar los costos, y usar una variedad de lenguajes de desarrollo comunes.
Sin embargo, la flexibilidad de los contenedores también es atractiva. Con la capacidad de elegir cualquier lenguaje, cualquier biblioteca y cualquier objeto binario, los contenedores te ofrecen lo mejor de ambos mundos: la comodidad de la computación sin servidores y la flexibilidad de los contenedores. De eso se trata Cloud Run.
Aprender a usar Cloud Run no está dentro del alcance de este codelab. Consulta la documentación de Cloud Run. El objetivo aquí es que aprendas a alojar en contenedores tu app de App Engine para Cloud Run (u otros servicios alojados en contenedores). Existen algunos aspectos que debes saber antes de continuar, principalmente que tu experiencia de usuario será un poco diferente.
En este codelab, aprenderás a compilar e implementar contenedores. Aprenderás a hacer lo siguiente:
- Organiza tu app en contenedores con Jib
- Migra desde la configuración de App Engine
- y, de manera opcional, definir los pasos de compilación para Cloud Build.
Esto implicará dejar de usar ciertas funciones específicas de App Engine. Si prefieres no seguir esta ruta de acceso, puedes actualizar a un entorno de ejecución de Java 11/17 y, al mismo tiempo, mantener tus apps en App Engine.
3. Configurar/trabajo previo
1. Configura el proyecto
En este instructivo, usarás una app de ejemplo del repositorio appengine-java-migration-samples en un proyecto nuevo. Asegúrate de que el proyecto tenga una cuenta de facturación activa.
Si piensas trasladar una app existente de App Engine a Cloud Run, puedes usarla para continuar.
Ejecuta el siguiente comando para habilitar las APIs necesarias para tu proyecto:
gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com
2. Obtén la app de ejemplo del modelo de referencia
Clona la app de ejemplo en tu propia máquina o en Cloud Shell y, luego, navega a la carpeta baseline.
El ejemplo es una app de Datastore basada en servlets de Java 8 diseñada para su implementación en App Engine. Sigue las instrucciones del archivo README para preparar esta app para la implementación de App Engine.
3. Implementa la app de modelo de referencia (opcional)
La siguiente información solo es necesaria si quieres confirmar que la app funciona en App Engine antes de migrar a Cloud Run.
Consulta los pasos que se indican en README.md:
- Instala la CLI de
gcloud
o vuelve a familiarizarte con ella - Inicializa la CLI de gcloud para tu proyecto con
gcloud init
- Crea el proyecto de App Engine con
gcloud app create
- Implementa la app de ejemplo en App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
- Confirma que la app se ejecute en App Engine sin problemas.
4. Crea un repositorio de Artifact Registry
Después de crear contenedores para tu app, necesitarás un lugar para enviar y almacenar las imágenes. La forma recomendada de hacerlo en Google Cloud es con Artifact Registry.
Crea el repositorio llamado migration
con gcloud de la siguiente manera:
gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"
Ten en cuenta que este repositorio usa el tipo de formato docker
, pero hay varios tipos de repositorios disponibles.
En este punto, tienes tu app de App Engine de referencia, y tu proyecto de Google Cloud está preparado para migrarla a Cloud Run.
4. Modifica los archivos de la aplicación
En los casos en que tu app use mucho los servicios agrupados heredados de App Engine, la configuración o alguna otra función exclusiva de App Engine, te recomendamos seguir accediendo a esos servicios mientras actualizas al entorno de ejecución nuevo. En este codelab, se muestra una ruta de migración para aplicaciones que ya usan servicios independientes o que se pueden refactorizar para hacerlo.
1. Actualiza a Java 17
Si tu app está en Java 8, considera actualizar a una versión candidata de LTS posterior, como 11 o 17, para mantenerte al día con las actualizaciones de seguridad y obtener acceso a nuevas funciones del lenguaje.
Para comenzar, actualiza las propiedades de tu pom.xml
para incluir lo siguiente:
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
Esto establecerá la versión del proyecto en 17, le informará al complemento del compilador que deseas acceder a las funciones del lenguaje Java 17 y que deseas que las clases compiladas sean compatibles con la JVM de Java 17.
2. Cómo incluir un servidor web
Existen varias diferencias entre App Engine y Cloud Run que vale la pena tener en cuenta cuando se cambia entre ellos. Una diferencia es que, si bien el entorno de ejecución de Java 8 de App Engine proporcionaba y administraba un servidor Jetty para las apps que alojaba, Cloud Run no. Usaremos Spring Boot para proporcionarnos un servidor web y un contenedor de servlet.
Agrega las siguientes dependencias:
<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 servidor Tomcat de forma predeterminada, pero este ejemplo excluirá ese artefacto y se mantendrá con Jetty para minimizar las diferencias en el comportamiento predeterminado después de la migración. También podemos configurar la versión de Jetty para que coincida con la que proporciona App Engine de forma predeterminada.
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<jetty.version>9.4.46.v20220331</jetty.version>
</properties>
3. Configuración de Spring Boot
Si bien Spring Boot podrá volver a usar tus servlets sin modificaciones, requerirá cierta configuración para la visibilidad.
Crea la siguiente clase MigratedServletApplication.java
en el paquete 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);
}
}
Ten en cuenta que esto incluye la anotación @ServletComponentScan
, que buscará (en el paquete actual de forma predeterminada) cualquier @WebServlets
y los pondrá a disposición como se espera.
4. Empaqueta la app como un archivo JAR
Si bien es posible organizar tu app en contenedores con Jib a partir de un archivo war, es más fácil si la empaquetas como un archivo JAR ejecutable. Esto no requerirá mucha configuración, en particular para los proyectos que usan Maven como herramienta de compilación, ya que el empaquetado de jar es el comportamiento predeterminado.
Quita la etiqueta packaging
del archivo pom.xml
:
<packaging>war</packaging>
A continuación, agrega 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. Cómo migrar de la configuración, los servicios y las dependencias de App Engine
Como se mencionó al comienzo del codelab, Cloud Run y App Engine están diseñados para ofrecer diferentes experiencias del usuario. Algunas funciones que App Engine ofrece de forma predeterminada, como los servicios de Cron y Task Queue, deben volver a crearse de forma manual y se analizarán con más detalle en módulos posteriores.
La app de ejemplo no usa servicios agrupados en paquetes heredados, pero los usuarios cuyas apps sí lo hacen pueden consultar las siguientes guías:
- Migra desde servicios en paquetes para encontrar servicios independientes adecuados.
- Migra archivos de configuración XML a YAML para los usuarios que migran a los entornos de ejecución de Java 11/17 y permanecen en App Engine.
Como implementarás en Cloud Run a partir de ahora, se puede quitar 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. Cómo organizar la aplicación en contenedores
En este punto, puedes implementar tu app en Cloud Run de forma manual directamente desde tu código fuente. Esta es una excelente opción que usa Cloud Build en segundo plano para proporcionar una experiencia de implementación sin intervención. Analizaremos las implementaciones de origen con más detalle en módulos posteriores.
Como alternativa, si necesitas más control sobre la forma en que se implementa tu app, puedes definir un archivo cloudbuild.yaml
que describa de forma explícita los pasos de compilación que deseas seguir:
1. Define un archivo cloudbuild.yaml
Crea el siguiente archivo cloudbuild.yaml
en el mismo nivel que el pom.xml
:
steps:
# Test your build
- name: maven:eclipse-temurin
entrypoint: mvn
args: ["test"]
# Build with Jib
- name: maven:eclipse-temurin
entrypoint: mvn
args: [ "compile", "com.google.cloud.tools:jib-maven-plugin:3.2.1:build", "-Dimage=northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib"]
# Deploy to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args: [ 'run', 'deploy', 'visitors', '--image', 'northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib', '--region', 'northamerica-northeast1', '--allow-unauthenticated']
Una vez que le indiquemos a Cloud Build que siga estos pasos, hará lo siguiente:
- Ejecuta tus pruebas con
./mvnw test
- Compila, envía y etiqueta tu imagen a Artifact Registry con Jib
- Implementa tu imagen en Cloud Run con
gcloud run deploy
Ten en cuenta que ‘visitors'
se proporciona a Cloud Run como el nombre del servicio deseado. La marca –allow-unauthenticated
permite a los usuarios visitar la aplicación web sin requerir autenticación. Asegúrate de reemplazar PROJECT_ID por el ID de tu proyecto en el archivo cloudbuild.yaml
.
A continuación, agrega las siguientes vinculaciones de políticas de IAM para permitir que la cuenta de servicio de Cloud Build acceda a Artifact Registry:
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)" )
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role=roles/run.admin \
--project=$PROJECT_ID
gcloud iam service-accounts add-iam-policy-binding $PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role roles/iam.serviceAccountUser --project=$PROJECT_ID
2. Ejecuta el proceso de compilación
Ahora que informaste a Cloud Build sobre los pasos de compilación deseados, estás listo para una implementación con un clic.
Ejecuta el siguiente comando:
gcloud builds submit
Una vez que finaliza el proceso, se compila la imagen de contenedor, se almacena en Artifact Registry y se implementa en Cloud Run.
Al final de este codelab, tu app debería verse igual a la de java17-and-cloud-run/finish.
Lo logró. Migraste correctamente una app de App Engine de Java 8 a Java 17 y Cloud Run, y ahora tienes una comprensión más clara del trabajo que implica cambiar y elegir entre las opciones de hosting.
6. Resumen/limpieza
¡Felicitaciones! Actualizaste, alojaste en contenedores, migraste y actualizaste tu app, lo que concluye con este instructivo.
A partir de aquí, el siguiente paso es aprender más sobre las funciones de seguridad de CI/CD y de la cadena de suministro de software que están a tu alcance ahora que puedes implementar con Cloud Build:
- Crea pasos de compilación personalizados con Cloud Build
- Cómo crear y administrar activadores de compilación
- Usa el análisis a pedido en tu canalización de Cloud Build
Opcional: Limpia o inhabilita el servicio
Si implementaste la app de ejemplo en App Engine durante este instructivo, recuerda inhabilitar la app para evitar incurrir en cargos. Cuando estés listo para pasar al siguiente codelab, puedes volver a habilitarla. Aunque las apps de App Engine estén inhabilitadas, no recibirán tráfico que genere cargos. Sin embargo, el uso de Datastore puede facturarse si supera su cuota gratuita, así que borra lo suficiente para que quede dentro de ese límite.
Por otro lado, si no vas a continuar con las migraciones y quieres borrar todo el contenido por completo, puedes borrar tu servicio o cerrar el proyecto por completo.
7. Recursos adicionales
Problemas o comentarios de los Codelabs del módulo de migración de App Engine
Si encuentras algún problema con este Codelab, primero busca el problema antes de enviarlo. Vínculos para buscar y crear problemas nuevos:
Recursos de migración
- Opciones de migración para desincorporar servicios de App Engine
- Configura activadores de compilación para Cloud Build
- Más información para migrar a Java 11/17
Recursos en línea
A continuación, se incluyen recursos en línea que pueden ser relevantes para este instructivo:
App Engine
- Documentación de App Engine
- Información de precios y cuotas de App Engine
- Comparación de las plataformas de primera y segunda generación
- Asistencia a largo plazo para entornos de ejecución heredados
Otra información de la nube
- Nivel "Siempre gratis" de Google Cloud
- Google Cloud CLI (CLI de
gcloud
) - Toda la documentación de Google Cloud
Videos
- Serverless Migration Station
- Expediciones sin servidores
- Suscríbete a Google Cloud Tech
- Suscríbete a Google Developers
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.