Módulo 4: Migrar de Google App Engine a Cloud Run con Docker

Esta serie de Codelabs (instructivos prácticos y de autoaprendizaje) tienen como objetivo ayudar a los desarrolladores de Google App Engine (estándar) a modernizar sus apps con una serie de migraciones. Una vez que se realiza, los usuarios pueden lograr que sus apps sean más portátiles mediante la creación de 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 las aplicaciones de App Engine en contenedores a fin de implementar en el servicio completamente administrado de Docker, una plataforma conocida en la industria para desarrollar, enviar y ejecutar aplicaciones en contenedores. En los desarrolladores de Python 2, este instructivo INICIA con la app de ejemplo de App Engine para Cloud NDB del módulo 2 mientras que los desarrolladores de Python 3 INICIAN con la muestra del módulo 3 de Cloud Datastore.

Obtendrás información para hacer las siguientes acciones

  • Crea contenedores para tu aplicación mediante Docker
  • Implementa imágenes de contenedor en Cloud Run

Qué necesitará

Encuesta

¿Cómo usarás este codelab?

Solo te recomendamos que lo leas Léelo y completa los ejercicios

Los sistemas PaaS, como App Engine y Cloud Functions, ofrecen muchos beneficios para tu equipo y aplicación. Por ejemplo, estas plataformas sin servidores permiten que el administrador de sistemas y los desarrolladores se enfoquen en la compilación de soluciones. La 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 usa una variedad de lenguajes de desarrollo comunes.

Sin embargo, la flexibilidad de los contenedores también es atractiva, debido a la capacidad de elegir cualquier lenguaje, cualquier biblioteca y cualquier objeto binario. Brindamos a los usuarios lo mejor de ambos mundos, la comodidad de la computación sin servidores y la flexibilidad de los contenedores, es de lo que se trata Google 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). Existen algunos aspectos que debes saber antes de continuar, que tu experiencia de usuario será un poco diferente, un poco más bajo, dado que dejarás de implementar el código de la aplicación y de implementarlo.

En su lugar, deberás aprender algo sobre los contenedores, cómo compilarlos e implementarlos. También puedes decidir lo que deseas colocar en la imagen del contenedor, incluido un servidor web, dado que ya no usará el servidor web de App Engine. Si prefieres no seguir esta ruta de acceso, mantener tus apps en App Engine no es una opción adecuada.

En este instructivo, aprenderás a organizar en contenedores tu app, reemplazar los archivos de configuración de App Engine por la configuración de contenedores, determinar qué elementos hay en el contenedor y, luego, especificar cómo iniciar tu aplicación. App Engine maneja automáticamente muchas de estas tareas.

Esta migración incluye los siguientes pasos:

  1. Configurar/trabajo previo
  2. Crear contenedores para la aplicación
    • Reemplazar los archivos de configuración
    • Modificar archivos de aplicaciones

Antes de comenzar con la parte principal del instructivo, configuremos nuestro proyecto, obtengamos el código e implementemos la app de modelo de referencia para que comencemos a trabajar con el código.

1. Configura el proyecto

Si completaste los Codelabs del Módulo 2 o del Módulo 3, te recomendamos volver a usar los mismos proyectos (y el código). De manera alternativa, puedes crear un proyecto nuevo o reutilizar otro proyecto existente. Asegúrate de que el proyecto tenga una cuenta de facturación activa y que App Engine (app) esté habilitado.

2. Obtén app de ejemplo del modelo de referencia

Uno de los requisitos previos a este codelab es tener una app de ejemplo del módulo 2 o 3 que funcione. Si aún no tienes uno, lee los instructivos (vínculos anteriores) antes de avanzar. De lo contrario, si ya estás familiarizado con su contenido, puedes comenzar leyendo el código del módulo 2 o 3 que se encuentra a continuación.

Ya sea que uses el tuyo o el nuestro, el código del módulo 2 es el que ingresaremos para la versión de Python 2 de este instructivo, y de manera similar, el código del módulo 3 para Python 3. Este codelab del módulo 4 te guiará en cada paso y, según tus opciones, deberías terminar con un código que se parezca a una de las carpetas del repositorio del módulo 4 (FINALIZAR) cuando se complete.

El directorio de archivos de INICIO del módulo 2 de Python 2 (los tuyos o los nuestros) debe ser similar al siguiente:

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

Si usas tu propio código del módulo 2 (2.x), también podrás tener una carpeta lib. No se usan ni lib ni appengine_config.py para Python 3, en el que el código a fin de ingresar el módulo 3 (3.x) debe verse de la siguiente manera:

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

3. (vuelve a) implementa la aplicación de modelo de referencia

Los pasos del trabajo previo restantes para ejecutar ahora sin estos:

  1. Familiarízate con la herramienta de línea de comandos de gcloud
  2. Vuelve a implementar la app de muestra con gcloud app deploy
  3. Confirma que la app se ejecuta en App Engine sin problemas

Una vez que hayas ejecutado esos pasos de manera correcta, estás listo para alojarla en contenedores.

En la actualidad, Docker es la plataforma de creación de contenedores estándar en la industria. Un desafío sobre el uso de este, como se mencionó antes, es que se requiere un esfuerzo para seleccionar un Dockerfile eficaz, el archivo de configuración que determina cómo se compilan las imágenes de tu contenedor. Por otro lado, los Buildpacks requieren poco esfuerzo, ya que usan la introspección a fin de determinar las dependencias de tu app, lo que hace que el contenedor de Buildpacks sea lo más eficiente posible para tu app.

Se encuentra en el lugar correcto si ya conoces los contenedores, Docker y deseas obtener más información a fin de organizar tu aplicación de App Engine para Cloud Run. Si lo deseas, puedes usar el codelab del Módulo 5 (idéntico a este, pero con Cloud Buildpacks). Nuestra app de ejemplo barebones es lo suficientemente liviana para evitar algunos de esos problemas antes mencionados Dockerfile.

Los pasos de migración incluyen el reemplazo de los archivos de configuración de App Engine y la especificación de cómo se debe iniciar tu app. A continuación, se muestra una tabla que resume los archivos de configuración que se esperarán para cada tipo de plataforma. Compara la columna de App Engine con la columna de Docker (y, opcionalmente, los paquetes de compilación):

Descripción

App Engine

Docker

Paquetes de compilación

Configuración general

app.yaml

Dockerfile

(service.yaml)

Bibliotecas de terceros

requirements.txt

requirements.txt

requirements.txt

Configuración de terceros

app.yaml (más appengine_config.py y lib [solo para 2.x])

(n/a)

(n/a)

Inicio

(n/a) o app.yaml (si se usa entrypoint)

Dockerfile

Procfile

Ignora los archivos

.gcloudignore y .gitignore

.gcloudignore, .gitignore y .dockerignore

.gcloudignore y .gitignore

Una vez que tu aplicación está alojada en contenedores, se puede implementar en Cloud Run. Otras opciones de plataformas de contenedores de Google Cloud incluyen Compute Engine, GKE y Anthos.

Configuración general

La migración desde App Engine implica reemplazar app.yaml por un Dockerfile que describa cómo compilar y ejecutar el contenedor. App Engine inicia tu aplicación de forma automática, pero Cloud Run no. Esto es para los comandos Dockerfile, ENTRYPOINT y CMD. Obtén más información sobre Dockerfile en esta página de documentos de Cloud Run y consulta un ejemplo de Dockerfile que genera gunicorn.

Una alternativa para usar ENTRYPOINT o CMD en un Dockerfile es usar un Procfile. Por último, un objeto .dockerignore ayuda a filtrar archivos ajenos a la app para mantener el tamaño del contenedor más bajo. Próximamente agregaremos información adicional.

Borra app.yaml y crea Dockerfile

No se usa app.yaml en contenedores, por lo que debes bórrala ahora. El archivo de configuración del contenedor es Dockerfile y nuestra app de muestra solo requiere una mínima. Para crear tu Dockerfile con este contenido, reemplaza NNN con 2 o 3, según la versión de Python que uses:

FROM python:NNN-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "main.py"]

La mayoría de los Dockerfile especifica cómo crear el contenedor, exceptoENTRYPOINT, que especifique cómo iniciar el contenedor, en este caso, llamando a python main.py para ejecutar el servidor de desarrollo de Flask. Si eres nuevo en Docker, la directiva FROM indica la imagen base desde la que se debe comenzar, y “slim” hace referencia a una distribución mínima de Python. Obtén más información en la página de imágenes de Python de Docker.

El conjunto intermedio de comandos crea el directorio de trabajo (/app), copia en los archivos de la aplicación y, luego, ejecuta pip install para incorporar bibliotecas de terceros al contenedor. WORKDIR combina los comandos mkdir y cd de Linux. Obtén más información al respecto en la documentación de WORKDIR . Las directivas COPY y RUN son explicativas.

Bibliotecas de terceros

El archivo requirements.txt puede permanecer igual. Flask debería aparecer junto con la biblioteca cliente de Datastore (Cloud Datastore o Cloud NDB). Si deseas usar otro servidor HTTP compatible con WSGI, como Gunicorn, la versión actual al momento de esta escritura, es 20.0.4, agrega gunicorn==20.0.4 a requirements.txt.

Configuración de terceros

Los desarrolladores de Python 2 en App Engine saben que las bibliotecas de terceros se copian en la carpeta lib, como se indica en requirements.txt, están detalladas en app.yaml y son compatibles con appengine_config.py. Los contenedores, como las apps de App Engine en Python 3, solo usan requirements.txt, por lo que se pueden descartar todas las demás partes, lo que significa que, si tienes una app de App Engine 2.x, borra appengine_config.py y cualquier carpeta lib ahora.

Inicio

Los usuarios de Python 2 no inician el servidor web de App Engine, pero cuando se cambia a un contenedor, deben hacerlo. Para ello, se agrega una directiva CMD o ENTRYPOINT a tu Dockerfile que especifique la manera de iniciar tu app, y esto se describe a continuación de la misma manera que los usuarios de Python 3.

Los usuarios de Python 3 tienen la opción de convertir sus archivos app.yaml para tener un entrypoint, en lugar de directivas script: auto en su sección handlers. Si usas entrypoint en app.yaml de Python 3, se vería de la siguiente manera:

runtime: python38
entrypoint: python main.py

La directiva entrypoint indica a App Engine cómo iniciar tu servidor. Puedes moverlo casi directamente a tu Dockerfile (o Procfile si usas Buildpacks [consulta el módulo 5] para alojar la app en contenedores). Se resume dónde se iría una directiva de punto de entrada entre ambas plataformas:

  • Docker: línea en Dockerfile: ENTRYPOINT ["python", "main.py"]
  • Buildpacks: línea en Procfile: web: python main.py

Usar el servidor de desarrollo de Flask está bien a fin de realizar pruebas, pero si usas un servidor de producción como gunicorn para tu aplicación, asegúrate de apuntar tu directiva ENTRYPOINT o CMD al igual que en la muestra de la guía de inicio rápido de Cloud Run.

Ignora los archivos

Te recomendamos crear un archivo .dockerignore para cortar el tamaño de tu contenedor y no sobrecargar la imagen de contenedor con archivos superfluos como estos:

*.md
*.pyc
*.pyo
.git/
.gitignore
__pycache__

Archivos de aplicación

Todas las aplicaciones del módulo 2 o el módulo 3 son totalmente compatibles con Python 2 y 3, lo que significa que no hay cambios en los componentes principales de main.py. Solo agregaremos algunas líneas de código de inicio. Agrega un par de líneas en la parte inferior de main.py a fin de iniciar el servidor de desarrollo, ya que Cloud Run requiere que el puerto 8080 esté abierto para que pueda llamar a tu aplicación:

if __name__ == '__main__':
    import os
    app.run(debug=True, threaded=True, host='0.0.0.0',
            port=int(os.environ.get('PORT', 8080)))

Una vez que se hayan completado las actualizaciones de Docker y la configuración de archivos fuente, estará listo para que se ejecute en Cloud Run. Antes de eso, analizaremos con brevedad los servicios.

Comparación entre los servicios y las apps

Si bien App Engine se creó principalmente para alojar aplicaciones, también es una plataforma que aloja servicios web o aplicaciones que constan de una colección de microservicios. En Cloud Run, todo es un servicio, ya sea un servicio real o una aplicación con una interfaz web. Por lo tanto, considera su uso como la implementación de un servicio en lugar de una aplicación.

A menos que tu aplicación de App Engine esté compuesta por varios servicios, no tienes que escribir ningún nombre cuando implementas tus aplicaciones. Los cambios que realizas en Cloud Run lo hacen con un nombre de servicio. Por otro lado, el dominio appspot.com de App Engine tiene su ID del proyecto, p .ej., https://PROJECT_ID.appspot.com y tal vez la abreviatura del ID de región, p. ej., http://PROJECT_ID.REGION_ID.r.appspot.com.

Sin embargo, el dominio de un servicio de Cloud Run incluye el nombre de servicio, la abreviatura del ID de región y un hash, pero no el ID del proyecto, p. ej., https://SVC_NAME-HASH-REG_ABBR.a.run.app. En resumen, comienza a pensar en el nombre del servicio.

Implementar servicio

Ejecuta el siguiente comando para compilar su imagen de contenedor e implementarla en Cloud Run. Cuando se le solicite, seleccione su región y permita conexiones sin autenticación para realizar pruebas más fácilmente y seleccione su región según corresponda, en el que SVC_NAME es el nombre del servicio que implementará.

$ gcloud beta run deploy SVC_NAME --source .
Please choose a target platform:
 [1] Cloud Run (fully managed)
 [2] Cloud Run for Anthos deployed on Google Cloud
 [3] Cloud Run for Anthos deployed on VMware
 [4] cancel
Please enter your numeric choice:  1

To specify the platform yourself, pass `--platform managed`. Or, to make this the default target platform, run `gcloud config set run/platform managed`.

Please specify a region:
 [1] asia-east1
 [2] asia-east2
 [3] asia-northeast1
 [4] asia-northeast2
 [5] asia-northeast3
 [6] asia-south1
 [7] asia-southeast1
 [8] asia-southeast2
 [9] australia-southeast1
 [10] europe-north1
 [11] europe-west1
 [12] europe-west2
 [13] europe-west3
 [14] europe-west4
 [15] europe-west6
 [16] northamerica-northeast1
 [17] southamerica-east1
 [18] us-central1
 [19] us-east1
 [20] us-east4
 [21] us-west1
 [22] us-west2
 [23] us-west3
 [24] us-west4
 [25] cancel
Please enter your numeric choice: <select your numeric region choice>

To make this the default region, run `gcloud config set run/region REGION`.

Allow unauthenticated invocations to [SVC_NAME] (y/N)?  y

Building using Dockerfile and deploying container to Cloud Run service [SVC_NAME] in project [PROJECT_ID] region [REGION]
✓ Building and deploying new service... Done.
  ✓ Uploading sources...
  ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/BUILD-HASH?project=PROJECT_NUM].
  ✓ Creating Revision... Deploying Revision.
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [SVC_NAME] revision [SVC_NAME-00001-vos] has been deployed and is serving 100 percent of traffic.
Service URL: https://SVC_NAME-HASH-REG_ABBR.a.run.app

Visite la URL especificada con su navegador para confirmar que la implementación se realizó de forma correcta.

Como se indica en el comando gcloud, los usuarios pueden establecer varios parámetros de configuración predeterminados para reducir el resultado y la interactividad como se mostró antes. Por ejemplo, para evitar toda la interacción, puedes usar el siguiente comando de implementación de una línea:

$ gcloud beta run deploy SVC_NAME --source . --platform managed --region REGION --allow-unauthenticated

Si usas este, asegúrate de ser el mismo nombre de servicio SVC_NAME y el nombre de REGION que prefieras, no la selección de menú indexada, como hicimos de manera interactiva.

Confirma que la aplicación funcione en Cloud Run como en App Engine. Si alcanzaste esta serie sin hacer ninguno de los Codelabs anteriores, la aplicación en sí no cambia. Registra todas las visitas a la página web principal (/) y tendrá esta apariencia una vez que hayas visitado el sitio muchas veces:

app de visitme

El código ahora debe coincidir con el contenido de la carpeta del repositorio del módulo 4, ya sea 2.x3.x. Felicitaciones por completar este codelab del módulo 4.

Opcional: Limpieza

¿Qué te parece limpiar a fin de evitar que se te facture hasta que estés listo para pasar a la siguiente codelab de migración? Dado que ahora usa un producto diferente, asegúrate de consultar la guía de precios de Cloud Run.

Opcional: Inhabilita el servicio

Si aún no estás listo para continuar con el siguiente instructivo, inhabilita tu servicio a fin de evitar que se apliquen cargos adicionales. Cuando estés listo para pasar al siguiente codelab, puedes volver a habilitarla. Aunque tu app esté inhabilitada, no recibirá tráfico que genere cargos. Sin embargo, si se excede la cuota gratuita, se te cobrará por el uso de Datastore. 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.

Próximos pasos

¡Felicitaciones, alojaste tu aplicación en contenedores, lo que concluye con este instructivo! A partir de este punto, el siguiente paso es aprender a hacer lo mismo con Cloud Buildpacks en el codelab del módulo 5 (siguiente vínculo) o trabajar en otra migración de App Engine:

  • Si aún no lo has hecho, migra a Python 3. La app de muestra ya es compatible con 2.x y 3.x, por lo que el único cambio es que los usuarios de Docker actualicen su Dockerfile para usar una imagen de Python 3.
  • Módulo 5: Migra a Cloud Run con Cloud Buildpacks
    • Crea contenedores para tu app a fin de que se ejecute en Cloud Run con paquetes de Cloud Build
    • No necesitas saber nada sobre Docker, contenedores ni Dockerfile.
    • Requiere que ya hayas migrado tu app a Python 3
  • Módulo 7: Listas de tareas en cola de envío de App Engine (obligatorio si usas las listas de tareas en cola [enviar])
    • Agrega tareas de envío taskqueue de App Engine a la app del módulo 1
    • Prepara a los usuarios para la migración a Cloud Tasks en el módulo 8
  • Módulo 3:
    • Moderniza el acceso de Datastore de Cloud NDB a Cloud Datastore
    • Esta es la biblioteca que se usa para las aplicaciones de App Engine de Python 3 y las aplicaciones que no pertenecen a App Engine.
  • Módulo 6: Migra a Cloud Firestore
    • Migra a Cloud Firestore para acceder a las funciones de Firebase
    • Si bien Cloud Firestore es compatible con Python 2, este codelab solo está disponible en Python 3.

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

En la tabla que se encuentra a continuación, se pueden encontrar los vínculos a las carpetas del repositorio para los módulos 2 y 3 (INICIAR) y el módulo 4 (FINALIZAR). También se puede acceder a ellos desde el repositorio de todas las migraciones de codelab de App Engine, que te permite clonar o descargar un archivo ZIP.

Codelab

Python 2

Python 3

Módulo 2

código

(código)

Módulo 3

(código)

código

Módulo 4

código

código

Recursos de App Engine y Cloud Run

A continuación, se muestran recursos adicionales con respecto a esta migración específica: