De desarrollo a producción en tres pasos sencillos con Cloud Run

1. Introducción

¿Por qué es tan difícil administrar las aplicaciones?

Una de las principales razones es que los desarrolladores suelen tener que ser administradores de sistemas a tiempo parcial. Considera esta lista (parcial) de inquietudes para desarrollar, implementar y administrar una aplicación web moderna a nivel de producción :

4d018476b4a73b47.png

No sé tú, pero no quiero preocuparme de todo esto. Lo que realmente quiero pensar es la lógica de mi aplicación:

6dfd143d20e5548b.png

En pocas palabras, de eso se trata Cloud Run: te permite enfocarte en tu app y dejar toda la administración y el mantenimiento a cargo de otra persona, es decir Google, que invirtió millones de horas en perfeccionar y perfeccionar sus habilidades en este dominio.

Además de los desafíos administrativos mencionados anteriormente, también debes lidiar con lo siguiente:

  • Dependencias: El entorno en el que se ejecuta tu aplicación debe, siempre que sea posible, coincidir con precisión con el entorno en el que se probó. Esto puede abarcar varias dimensiones, incluido el sistema operativo, las bibliotecas de compatibilidad, el intérprete o compilador de lenguaje, la configuración de hardware y muchos otros factores.
  • Distribución: Pasar de una versión local de una app a una que se comparte ampliamente en Internet suele requerir un cambio en el entorno de ejecución, un salto cuántico en la complejidad y una curva de aprendizaje empinada.

Cloud Run se encarga de estas y muchas otras preocupaciones por ti. Pero en lugar de creer, compilaremos una app juntos y veamos lo fácil que es hacer la transición de un entorno de desarrollo local a una app en la nube de nivel de producción en unos pocos pasos sencillos.

Actividades

  • Compilarás una app web simple y verificarás que se ejecute como se espera en tu entorno de desarrollo.
  • Luego, pasarás a una versión alojada en contenedores de la misma app. En el camino, explorarás qué significa la creación de contenedores y por qué es tan útil.
  • Por último, implementarás tu app en la nube y verás lo fácil que es administrar tu servicio de Cloud Run con la línea de comandos y la consola de Google Cloud.

Qué aprenderás

  • Cómo crear una app de servidor web sencilla en Python
  • Empaquetar tu app en un contenedor de Docker que se ejecute en cualquier lugar
  • Cómo implementar tu app en la nube para que cualquier persona pueda probar tu creación nueva
  • Cómo simplificar aún más los pasos anteriores con Buildpacks
  • Cómo usar la herramienta de línea de comandos de Google Cloud y la IU web de la consola de Cloud

Qué necesitarás

  • Un navegador web
  • Una Cuenta de Google

Este lab está dirigido a desarrolladores de todos los niveles, incluidos principiantes. Si bien usarás Python, no es necesario que estés familiarizado con la programación de ese lenguaje para entender qué está sucediendo, ya que te explicaremos todo el código que uses.

2. Prepárate

5110b5081a1e1c49.png

En esta sección, se explica todo lo que debes hacer para comenzar este lab.

Configuración del entorno de autoaprendizaje

  1. Accede a la consola de Cloud y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Recuerde el ID de proyecto, un nombre único en todos los proyectos de Google Cloud (el nombre anterior ya se encuentra en uso y no lo podrá usar). Se mencionará más adelante en este codelab como PROJECT_ID.

  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar los recursos de Google Cloud recursos.

Ejecutar este codelab no debería costar mucho, tal vez nada. Asegúrate de seguir las instrucciones de la sección “Realiza una limpieza” en la que se aconseja cómo cerrar recursos para no incurrir en facturación más allá de este instructivo. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de$300.

Inicia Cloud Shell.

En este lab, trabajarás con una sesión de Cloud Shell, que es un intérprete de comandos alojado en una máquina virtual que se ejecuta en la nube de Google. Podrías ejecutar fácilmente esta sección de forma local, en tu computadora, pero Cloud Shell brinda una experiencia reproducible en un entorno coherente para todo el mundo. Después de este lab, puedes volver a probar esta sección en tu computadora.

704a7b7491bd157.png

Activar Cloud Shell

  1. En la consola de Cloud, haz clic en Activar Cloud Shell4292cbf4971c9786.png.

bce75f34b2c53987.png

Si nunca iniciaste Cloud Shell, aparecerá una pantalla intermedia (mitad inferior de la página) que describe en qué consiste. Si ese es el caso, haz clic en Continuar (y no volverás a verlo). Así es como se ve la pantalla única:

70f315d7b402b476.png

El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.

fbe3a0674c982259.png

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitas. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer simplemente con un navegador o tu Chromebook.

Una vez conectado a Cloud Shell, debería ver que ya se autenticó y que el proyecto ya se configuró con tu ID del proyecto.

  1. En Cloud Shell, ejecuta el siguiente comando para confirmar que está autenticado:
gcloud auth list

Resultado del comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Ejecuta el siguiente comando en Cloud Shell para confirmar que el comando de gcloud conoce tu proyecto:
gcloud config list project

Resultado del comando

[core]
project = <PROJECT_ID>

De lo contrario, puedes configurarlo con el siguiente comando:

gcloud config set project <PROJECT_ID>

Resultado del comando

Updated property [core/project].

Configura algunas variables de entorno en tu terminal que facilitarán el trabajo en los pasos posteriores:

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

Habilitación de las API

En pasos posteriores, verás en qué momento se necesitan estos servicios y por qué. Por ahora, ejecuta este comando para que tu proyecto pueda acceder a los servicios de Cloud Build, Container Registry y Cloud Run:

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

Si se realizó correctamente, se mostrará un mensaje similar a este:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. Compila una app web sencilla

eef530b56b8e93a3.png

Para comenzar, haz clic en el botón Open Editor que se encuentra en la parte superior del panel de Cloud Shell. El aspecto resultante será el siguiente:

9b81c8a37a6bcdd8.png

Luego, te encontrarás en un entorno IDE similar a Visual Studio Code, en el que puedes crear proyectos, editar código fuente, ejecutar tus programas, etc. Si tu pantalla está demasiado abarrotada, puedes expandir o reducir la línea divisoria entre la consola y tu ventana de edición o terminal arrastrando la barra horizontal entre esas dos regiones, destacadas aquí:

8dea35450851af53.png

Puedes alternar entre el editor y la terminal haciendo clic en los botones Open Editor y Open Terminal, respectivamente. Ahora intenta alternar entre estos dos entornos.

A continuación, crea una carpeta en la que almacenarás tu trabajo para este lab. Para ello, selecciona Archivo -> Carpeta nueva, ingresa hello y haz clic en OK. Todos los archivos que crees en este lab y todo el trabajo que hagas en Cloud Shell tendrán lugar en esta carpeta.

Ahora, crea un archivo requirements.txt. Esto le indica a Python de qué bibliotecas depende tu app. En esta app web sencilla, usarás un módulo popular de Python para compilar servidores web llamado Flask y un framework de servidor web llamado gunicorn. En la ventana de Cloud Editor, haz clic en el menú Archivo -> Nuevo archivo para crear un archivo nuevo. Cuando se te solicite el nombre del archivo nuevo, ingresa requirements.txt y presiona el botón OK. Asegúrate de que el archivo nuevo termine en la carpeta del proyecto hello.

Ingresa las siguientes líneas en el archivo nuevo para especificar que tu aplicación depende del paquete Flask de Python y del servidor web gunicorn.

Flask
gunicorn

No es necesario que guardes este archivo de forma explícita, ya que el Editor de Cloud guardará automáticamente los cambios.

Versión 1: Hello World!

Con la misma técnica, crea otro archivo nuevo llamado main.py. Este será el archivo fuente de Python principal (y único) de tu app. Una vez más, asegúrate de que el archivo nuevo termine en la carpeta del proyecto hello.

Inserta el siguiente código en este archivo:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Vuelve a la terminal y cambia a la carpeta del proyecto con este comando:

cd hello

Ejecuta el siguiente comando para instalar las dependencias de tu proyecto:

pip3 install -r requirements.txt

Ahora inicia tu app ejecutando este comando en la terminal:

python3 main.py

En este punto, tu app se está ejecutando en la máquina virtual dedicada a tu sesión de Cloud Shell. Cloud Shell incluye un mecanismo de proxy que te permite acceder a los servidores web (como el que acabas de iniciar) que se ejecutan en tu máquina virtual desde cualquier lugar de Internet global.

Haz clic en el botón web preview y, luego, en el elemento de menú Preview on Port 8080 de la siguiente manera:

fe45e0192080efd6.png

Esto abrirá una pestaña del navegador web en tu app en ejecución, que debería verse de la siguiente manera:

b1f06501509aefb9.png

Versión 2: Cómo hacer eco de la ruta de URL

Regresa a Cloud Editor (a través del botón Open Editor) y agrega compatibilidad con la repetición de un sufijo de URL opcional. Para ello, actualiza tu archivo main.py de la siguiente manera:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Vuelve a la terminal (con el botón Open Terminal) y, luego, ingresa control-C (mantén presionada la tecla Control mientras presionas “C”) para detener la app en ejecución y, luego, reiníciala ingresando lo siguiente:

python3 main.py

Nuevamente, haz clic en el botón web preview y, luego, en el elemento de menú Preview on Port 8080 para abrir una pestaña del navegador web de tu app en ejecución. Deberías volver a ver el mensaje “Hello World!” pero ahora reemplaza el texto de la URL que sigue al carácter de barra por cualquier cadena que elijas (p.ej., /your-name) y verifica que veas algo como esto:

93b87996f88fa370.png

Versión 3: Colores aleatorios

Ahora, regresa a Cloud Editor (a través del botón Open Editor) y actualiza tu archivo main.py de la siguiente manera para agregar compatibilidad con colores de fondo aleatorios:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Vuelve a la terminal (con el botón Open Terminal) y, luego, ingresa control-C (mantén presionada la tecla Control mientras presionas “C”) para detener la app en ejecución y, luego, reiníciala ingresando lo siguiente:

python3 main.py

Nuevamente, haz clic en el botón web preview y, luego, en el elemento de menú Preview on Port 8080 para abrir una pestaña del navegador web de tu app en ejecución. Deberías ver el texto generado, con cualquier sufijo especificado o el valor predeterminado "Hello World!". que se muestra frente a un fondo de color aleatorio, como se muestra a continuación:

baf8d028f15ea7f4.png

Vuelve a cargar la página algunas veces para ver si el color de fondo aleatorio cambia cada vez que visitas la app.

Con esto, tu app está lista. ¡Felicitaciones! En el siguiente paso, aprenderás a empaquetar tu app en un contenedor y por qué resulta útil hacerlo.

4. Aloja tu app en contenedores

17cc234ec3325a8a.png

¿Qué es un contenedor?

Los contenedores en general, y Docker en particular, nos dan la capacidad de crear una caja modular en la que ejecutar una aplicación con todas sus dependencias agrupadas. Llamamos al resultado una imagen de contenedor. En esta sección, crearás una imagen de contenedor, que usarás para encapsular tu aplicación y todas sus dependencias.

Hablando de dependencias, en un paso anterior, cuando ejecutabas tu app en un entorno de desarrollador, tenías que ejecutar pip3 install -r requirements.txt y asegurarte de que el archivo requirements.txt contenía todas tus bibliotecas dependientes y versiones correspondientes. Con los contenedores, esos requisitos se instalan cuando generas la imagen de contenedor, por lo que el consumidor del contenedor no tiene que preocuparse por instalar nada.

Esta imagen de contenedor formará el componente básico para implementar tu aplicación en Cloud Run. Debido a que los contenedores se pueden usar en casi cualquier servidor virtual o real, esto nos brinda una forma de implementar tu aplicación en cualquier lugar que desees y de moverla de un proveedor de servicios a otro, o de un entorno local a la nube.

Los contenedores ayudan a que tus aplicaciones tengan las siguientes características:

  • reproducibles: los contenedores son independientes y están completos.
  • Portátil: Los contenedores son componentes básicos multiindustria que permiten la portabilidad de las aplicaciones entre proveedores y entornos de nube.

En resumen, los contenedores ofrecen la capacidad, finalmente, de “escribir una vez y ejecutar en todas partes”. Una excepción a esta regla es que el contenedor generado está limitado a ejecutarse en el tipo de procesador en el que lo creaste, pero también hay formas de generar versiones del contenedor para otras configuraciones de hardware.

Basta de hablar. ¡Creemos un contenedor! Usarás una tecnología específica para crear un contenedor llamado Docker.

En el Editor de Cloud, crea un archivo nuevo llamado Dockerfile. Este archivo es un plano para construir tu imagen. Le indica a Docker sobre tu entorno operativo y tu código fuente, cómo instalar tus dependencias, compilar tu app y ejecutar tu código.

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

En la terminal de Cloud, compila tu imagen de contenedor con Cloud Build. Para ello, ejecuta el siguiente comando:

gcloud builds submit --tag $TAG

Una vez enviado al registro, verás un mensaje SUCCESS con el nombre de la imagen, que debería verse de la siguiente manera: gcr.io/<project-id>/hello. Ahora la imagen se almacena en Google Container Registry y se puede volver a usar en cualquier momento y lugar.

Puedes obtener una lista de todas las imágenes de contenedores asociadas a tu proyecto actual con este comando:

gcloud container images list

Ahora ejecuta y prueba la aplicación localmente desde Cloud Shell con los siguientes comandos de docker:

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

La opción -p $PORT:$PORT le indica a Docker que asigne el puerto externo $PORT (configurado en 8080, arriba) en el entorno de host al mismo número de puerto dentro del contenedor en ejecución. Esto facilita la tarea, ya que el código del servidor que escribes y el número de puerto externo al que te conectas cuando pruebas tu app serán los mismos (8080), pero también podrías usar la opción -p para asignar cualquier puerto externo arbitrario en el host al puerto interno deseado dentro del contenedor.

La opción -e PORT=$PORT le indica a Docker que ponga la variable de entorno $PORT (establecida en 8080 antes) para la app que se ejecuta dentro del contenedor.

Ya está todo listo para probar la app. Para ello, apunta un navegador web al código de Python que se ejecuta en el contenedor. En la ventana de Cloud Shell, haz clic en la “Vista previa en la Web”. y selecciona "Vista previa en el puerto 8080", como lo hiciste en el paso anterior.

El resultado debería resultarte familiar, ya que deberías ver el texto generado frente a un fondo de color aleatorio, tal como lo hiciste cuando ejecutaste la app directamente en tu terminal de Cloud Shell. Vuelve a cargar la página algunas veces para ver si el color de fondo aleatorio cambia cada vez que visitas la app.

¡Felicitaciones! Ya ejecutaste una versión alojada en contenedores de tu app. En la siguiente sección, sin modificar ninguna línea de código, convertirás tu imagen de contenedor en una app web de calidad de producción.

5. A la nube...

1b0665d94750ded6.gif

Ahora que creaste un contenedor para tu app, es recomendable que compartas esta genialidad con el resto del mundo, por lo que es hora de implementarla en la nube. Pero realmente quieres hacer algo más que solo compartirlo. Debes asegurarte de lo siguiente:

  • funciona de manera confiable. Obtienes tolerancia a errores automática en caso de que falle una computadora que ejecuta tu aplicación.
  • Escala automáticamente: tu app se mantiene al día con los amplios niveles de tráfico y reduce automáticamente su huella cuando no se usa.
  • Minimiza los costos, ya que no te cobra por los recursos que no usas: se te cobra solo por los recursos consumidos mientras respondes al tráfico
  • es accesible con un nombre de dominio personalizado: tienes acceso a una solución de un solo clic para asignar un nombre de dominio personalizado a tu servicio
  • ofrece un tiempo de respuesta excelente: los inicios en frío responden de una manera razonable, pero se puede ajustar si especificas una configuración de instancia mínima.
  • admite la encriptación de extremo a extremo con la seguridad web SSL/TLS estándar: cuando se implementa un servicio, se obtiene de forma gratuita y automática la encriptación web estándar y los certificados correspondientes

Si implementas tu app en Google Cloud Run, obtendrás todo lo anterior y mucho más.

Implementa tu app en Cloud Run

Primero, modifiquemos tu app para que puedas diferenciar la revisión nueva de la anterior. Para ello, modifica el archivo main.py de modo que el mensaje predeterminado cambie de "Hello world!" por “Hello from Cloud Run!”. En otras palabras, cambia esta línea de main.py por la siguiente:

def say_hello(name="world"):

a esto:

def say_hello(name="from Cloud Run"):

Cloud Run es regional, lo que significa que la infraestructura que ejecuta tus servicios se ubica en una región específica, y Google la administra para que esté disponible de manera redundante en todas las zonas de esa región. En la sección "Configurar", en la sección anterior, definiste una región predeterminada mediante la variable de entorno REGION.

Vuelve a compilar tu imagen de contenedor y, luego, implementa tu aplicación alojada en contenedores en Cloud Run con el siguiente comando:

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • También puedes definir una región predeterminada con gcloud config set run/region $REGION.
  • La opción --allow-unauthenticated hace que el servicio esté disponible de forma pública. Para evitar solicitudes sin autenticar, usa --no-allow-unauthenticated en su lugar.

La imagen que se especifica aquí es la imagen de Docker que compilaste en el último paso. Gracias al servicio Cloud Build, que almacenó la imagen resultante en Google Container Registry, el servicio de Cloud Run puede encontrarla e implementarla por ti.

Espere un momento a que finalice la implementación. Si la operación es exitosa, la línea de comandos mostrará la URL de servicio:

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

También puedes recuperar la URL del servicio con el siguiente comando:

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

Se debería mostrar algo como lo siguiente:

https://hello-....a.run.app

Este vínculo es una URL dedicada, con seguridad TLS, para tu servicio de Cloud Run. Este vínculo es permanente (siempre que no inhabilites el servicio) y se puede usar en cualquier lugar de Internet. No usa el mecanismo de proxy de Cloud Shell mencionado anteriormente, que dependía de una máquina virtual transitoria.

Haz clic en el Service URL destacado para abrir una pestaña del navegador web de tu app en ejecución. El resultado debería mostrar el mensaje “Hello from Cloud Run!” frente a un fondo de color aleatorio.

¡Felicitaciones! Tu app ahora se ejecuta en Google Cloud. Sin tener que pensarlo, tu app está disponible públicamente, con encriptación TLS (HTTPS) y ajuste de escala automático a niveles de tráfico asombrosos.

Pero creo que este proceso podría ser aún más fácil...

6. Crea el contenedor Automágicamente

Esto es genial, pero ¿qué pasa si no quiero pensar en los Dockerfiles y los contenedores? ¿Y si, como la mayoría de los desarrolladores, solo quiero enfocarme en escribir el código de mi aplicación y dejar que otra persona se preocupe por la creación de contenedores? Es tu suerte porque Cloud Run admite un estándar de código abierto llamado Buildpacks, que existe por este motivo: automatizar el proceso de fabricación de un contenedor a partir de una colección de archivos fuente.

Ten en cuenta que hay algunos casos en los que un desarrollador podría preferir usar un Dockerfile explícito, por ejemplo, si desea un alto grado de personalización en la forma en que se compila su contenedor. Sin embargo, para casos comunes como este ejercicio, los paquetes de compilación funcionan bien y evitan la necesidad de crear un Dockerfile de forma manual. Modifica tu código para usar paquetes de compilación.

Primero, modifiquemos tu app para que puedas diferenciar la revisión nueva de la anterior. Para ello, modifica el archivo main.py de modo que el mensaje predeterminado cambie de “Hello from Cloud Run!”. por “Hello from Cloud Run with Buildpacks!”. En otras palabras, cambia esta línea de main.py por la siguiente:

def say_hello(name="from Cloud Run"):

a esto:

def say_hello(name="from Cloud Run with Buildpacks"):

Ahora, aprovechemos los paquetes de compilación y cree un archivo nuevo llamado Procfile. Crea ese archivo en Cloud Editor e inserta esta línea de texto:

web: python3 main.py

Esto le indica al sistema de compilación cómo ejecutar tu app en el contenedor generado automáticamente. Con esa instrucción, ya ni siquiera necesitas un Dockerfile. Para verificar esto, borra el Dockerfile y ejecuta el siguiente comando en la terminal de Cloud Shell:

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

Esto es similar al comando que ejecutaste para implementar tu app en el último paso, pero esta vez reemplazaste la opción --image por --source .. Esto le indica al comando gcloud que deseas que use paquetes de compilación para crear tu imagen de contenedor, en función de los archivos de origen que encuentre en el directorio actual (dot en --source . es la abreviatura del directorio actual). Como el servicio se encarga de la imagen del contenedor de forma implícita, no necesitas especificar una imagen en este comando gcloud.

Una vez más, verifica que esta implementación haya funcionado haciendo clic en el Service URL destacado para abrir una pestaña del navegador web de tu app en ejecución y asegurarte de que tu servicio muestre “Hello from Cloud Run with Buildpacks!”. frente a un fondo de colores aleatorios.

Ten en cuenta que, con el uso de paquetes de compilación para fabricar tu Dockerfile, básicamente redujiste a dos los tres pasos sencillos:

  1. Crea una app en tu entorno de desarrollo.
  2. Implementa exactamente el mismo código en la nube con un comando.

7. ¿Debo usar la línea de comandos?

¡No! Como casi todos los servicios de Google Cloud, hay tres formas de interactuar con Cloud Run:

  • La herramienta de línea de comandos de gcloud, que acabas de ver.
  • Una interfaz de usuario web enriquecida, a través de la consola de Cloud, que admite un estilo intuitivo de interacción de apuntar y hacer clic.
  • De manera programática, con las bibliotecas cliente de Google disponibles para muchos lenguajes populares, como Java, C#, Python, Go, JavaScript, Ruby, C/C++ y otros.

Implementaremos una instancia adicional de tu app de Cloud Run con la IU de la consola. Navega a la página de destino del servicio de Cloud Run a través del menú de la parte superior izquierda:

e2b4983b38c81796.png

Luego, deberías ver un resumen de tus servicios de Cloud Run, como el siguiente:

b335e7bf0a3af845.png

Haz clic en “Crear servicio” vínculo para comenzar el proceso de implementación:

51f61a8ddc7a4c0b.png

Ingresa "hola de nuevo" como el nombre del servicio, toma la plataforma y la región de implementación predeterminadas y haz clic en “Siguiente”.

8a17baa45336c4c9.png

Ingresa esta URL para la imagen de contenedor: gcr.io/cloudrun/hello, que es un contenedor creado por Google con fines de prueba, y haz clic en "Configuración avanzada" para ver algunos de los distintos parámetros de configuración disponibles. Puedes personalizar algunos de ellos:

  • número de puerto y punto de entrada del contenedor (que anulará el punto de entrada especificado cuando se compila el contenedor)
  • hardware: memoria y cantidad de CPU
  • escalamiento: instancias mínimas y máximas
  • variables de entorno
  • otros: configuración de tiempo de espera de solicitudes, cantidad máxima de solicitudes por contenedor, HTTP/2

Haz clic en el botón "Siguiente" para avanzar en el diálogo. En el siguiente diálogo, puedes especificar cómo se activa tu servicio. En "Entrada", selecciona "Permitir todo el tráfico" y, en "Autenticación", selecciona "Permitir tráfico no autenticado".

e78281d1cff3418.png

Esta es la configuración más liberal, ya que permite que cualquier persona acceda a tu app de Cloud Run, desde cualquier lugar de la Internet pública, sin especificar credenciales de autenticación. Es posible que quieras una configuración más restrictiva para tu app, pero mantenlo simple para este ejercicio de aprendizaje.

Ahora, haz clic en el botón Create para crear tu servicio de Cloud Run. Después de unos segundos, deberías ver tu servicio nuevo en la lista de resumen de servicios de Cloud Run. La línea de resumen proporciona la implementación más reciente (fecha, hora y quién) junto con algunos parámetros de configuración clave. Haz clic en el vínculo del nombre del servicio para desglosar los detalles de tu nuevo servicio.

Para verificar tu servicio, haz clic en la URL que se muestra cerca de la parte superior de la página de resumen, como se destaca en el siguiente ejemplo:

6c35cf0636dddc51.png

Debería ver algo como esto:

3ba6ab4fe0da1f84.png

Ahora que implementaste un servicio nuevo de Cloud Run, selecciona la pestaña REVISIONS para ver algunas formas de administrar varias implementaciones.

2351ee7ec4a356f0.png

Para implementar revisiones nuevas directamente desde la consola, puedes hacer clic en el botón EDIT & DEPLOY NEW REVISION, como se destaca en la siguiente captura de pantalla de ejemplo:

a599fa88d00d6776.png

Haz clic en ese botón ahora para crear una nueva revisión. Cerca de la URL del contenedor, haz clic en el botón SELECT, como se muestra a continuación:

5fd1b1f8e1f11d40.png

En el diálogo que aparece, busca la aplicación web simple que implementaste antes desde Cloud Build con Buildpacks y haz clic en Seleccionar. Asegúrate de elegir la imagen de contenedor

gcr.io/<project>/cloud-run-source-deploy

folder de la siguiente manera:

8a756c6157face3a.png

Una vez que la selecciones, desplázate hasta la parte inferior y haz clic en el botón DEPLOY. Ya implementaste una revisión nueva de tu aplicación. Para verificarlo, vuelve a visitar la URL de tu servicio y verifica que ahora ves el mensaje colorido “Hello from Cloud Run with Buildpacks!”. aplicación web.

Como puedes ver, la pestaña de revisiones proporciona un resumen de cada revisión que implementaste y, ahora, deberías ver dos revisiones para este servicio. Para seleccionar una revisión determinada, haz clic en el botón de selección que se encuentra a la izquierda del nombre de la revisión, lo que mostrará un resumen de los detalles de la revisión a la derecha de la pantalla. Si seleccionas esos botones, puedes ver que las dos revisiones derivan de dos imágenes de contenedor diferentes.

El botón MANAGE TRAFFIC te permite modificar la distribución de las solicitudes entrantes que se envían a una revisión determinada. Esta capacidad para ajustar la cantidad de tráfico que se envía a una revisión determinada habilita varios casos de uso valiosos:

  • La prueba de versiones canary de una versión nueva de tu app con una pequeña parte del tráfico entrante
  • revertir el tráfico de una versión problemática a una revisión anterior
  • Pruebas A/B

Busca el botón MANAGE TRAFFIC aquí:

519d3c22ae028287.png

Configura una división del tráfico 50/50 entre tus dos revisiones especificando una división del tráfico 50/50 de la siguiente manera:

8c37d4f115d9ded4.png

Ahora haz clic en el botón GUARDAR y verifica la división 50/50 visitando la URL de tu servicio varias veces y verifica que, en promedio, la mitad de tus solicitudes las entregue la revisión actual ("Hello from Cloud Run with Buildpacks!") y la otra versión anterior ("¡Está en ejecución!").

Otras pestañas de la página Detalles del servicio ofrecen la capacidad de supervisar el rendimiento, el tráfico y los registros, lo que proporciona estadísticas valiosas sobre qué tan bien funciona tu servicio y qué tan bien. También puedes optimizar el acceso a tu servicio mediante los permisos . Tómate un momento para explorar las pestañas de esta página y hacerte una idea de las funciones disponibles.

Interfaz programática

Como se mencionó antes, también tienes la opción de crear, implementar y administrar tus servicios de Cloud Run de manera programática. Para las tareas manuales, esta opción es más avanzada que la línea de comandos o la consola web, pero sin duda es la mejor forma de automatizar los servicios de Cloud Run. Tienes la opción de usar las bibliotecas cliente de Google en varios lenguajes de programación populares.

8. Cómo probar tu app

198ada162d1f0bf1.png

En este paso final, ejecutarás una prueba de carga artificial para realizar una prueba de esfuerzo de tu app y observarás cómo se escala con la demanda entrante. Usarás una herramienta llamada hey, que está preinstalada en Cloud Shell y nos permite ejecutar pruebas de carga y presentar los resultados.

Ejecuta la prueba

En la terminal de Cloud Shell, ejecuta este comando para ejecutar una prueba de carga:

hey -q 1000 -c 200 -z 30s https://hello-...run.app

Los argumentos del comando se interpretan de la siguiente manera:

  • -q 1000: Intenta impulsar la carga a aproximadamente 1,000 solicitudes por segundo
  • -c 200: Asigna 200 trabajadores paralelos.
  • -z 30s: Ejecuta la prueba de carga durante 30 segundos.
  • asegúrate de usar tu URL de servicio como el último argumento en esta línea de comandos

Los resultados de la prueba deberían verse de la siguiente manera:

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

Este resumen nos indica varios elementos de interés:

  • Se enviaron 32,918 solicitudes a aproximadamente 1,000 por segundo durante 30 s.
  • No hubo errores (solo 200 respuestas HTTP).
  • La latencia promedio fue de 180 ms.
  • La latencia mínima fue de 107 ms y, en el peor de los casos, de 3.3 s
  • La latencia del percentil 90 fue de 244 ms.

Si consultas la pestaña METRICS en la consola de Cloud Run, podrás ver el lado del servidor de la historia de rendimiento:

e635c6831c468dd3.png

9. Limpieza

Si bien Cloud Run no cobra cuando el servicio no se usa, es posible que se te cobre por el almacenamiento de la imagen del contenedor compilada.

Puedes borrar tu proyecto de GCP para evitar incurrir en cargos, lo que detendrá la facturación de todos los recursos usados en ese proyecto, o simplemente borrar tu imagen de contenedor con el siguiente comando:

gcloud container images delete $TAG

Para borrar tus servicios de Cloud Run, usa estos comandos:

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. ¡Lo lograste!

9a31f4fdbbf1ddcb.png

Felicitaciones, compilaste e implementaste correctamente una app de producción de Cloud Run. En el camino, aprendiste sobre los contenedores y cómo compilar uno propio. También viste lo fácil que es implementar tu app con Cloud Run mediante la herramienta de línea de comandos de gcloud y la consola de Cloud. ¡Ahora ya sabes cómo compartir tus brillantes creaciones con todo el mundo!

Quiero dejarte una pregunta importante:

Una vez que la app funcionaba en tu entorno de desarrollador, ¿cuántas líneas de código tuviste que modificar para implementarla en la nube, con todos los atributos de nivel de producción que ofrece Cloud Run?

Por supuesto, la respuesta es cero. :)

Codelabs para revisar...

Otras funciones interesantes para explorar...

Documentos de referencia

11. Llamado a la acción

Logotipo de Google Cloud

Si te gustó este codelab y es probable que dediques más tiempo a la práctica con Google Cloud, deberías unirte a Google Cloud Innovators hoy mismo.

Logotipo de la insignia de miembro general de Innovators

Google Cloud Innovators es gratuito y también incluye lo siguiente:

  • Debates, sesiones de preguntas y sesiones de planificación en vivo para conocer las novedades más recientes directamente de los Googlers
  • las noticias más recientes de Google Cloud en tu bandeja de entrada
  • Insignia digital y fondo de videoconferencia
  • 500 créditos de labs y aprendizaje en Skills Boost

Haz clic aquí para registrarte.