Google Cloud Run 101
Tags: googlecloud, docker, spanish
Published: 2021-01-22 18:16:55

Conoce Cloud Run y despliega una aplicación en la nueva plataforma de Google para contenedores.

## ¿Qué es Google Cloud Run?

Es una plataforma para ejecutar contenedores de forma totalmente administrada (aka *serverless*) que se ejecuta en Google Cloud, basada en knative y kubernetes.

## Características de Cloud Run

Algunas de las características que hacen a Cloud Run una alternativa interesante son:

- Puedes usar cualquier lenguaje de programación, librería o programas del sistema operativo, siempre y cuando esté empaquetado en un contenedor

- Sólo pagas por el tiempo en que los contenedores atienden tu petición, si tu servicio no atiende peticiones, ¡Simplemente no pagas nada!

- Puedes configurar el auto escalamiento de tus contenedores, para atender más peticiones *on-demand* 

- Provee auto-balanceamiento, redundancia, seguridad HTTPs por default, administración de logs y monitoreo 

- Tiene una couta gratis de 50 vCPU-horas al mes


## ¿Porqué elegir Cloud Run en lugar de Cloud Functions?

La otra solución de aplicaciones *serverless* de Google Cloud es Cloud Functions, la cuál permite ejecutar aplicaciones sin administración de servidores, pero sólo están disponibles para PHP, Python, Javascript y Go con el entorno de desarrollo de Google (SDK), así que el uso de librerías, versiones de lenguaje y dependencias está restringida por el entorno que Google mantiene.


## ¿Qué necesito para ejecutar contenedores sobre Google Cloud Run?

El punto clave de Cloud Run es que tu servicio web (HTTP o gRPC) funcionaría sin modificaciones, siempre y cuando respete las condiciones de ejecución:

- El CPU está activo mientras procesa una petición HTTP, es decir mientras el contenedor esté en ejecución *pasiva* (sin atender peticiones), prácticamente no tendrá acceso al CPU.

- El acceso al sistema de archivos local es limitado, todo archivo que se escriba por tu aplicación se cargará en memoria RAM del contenedor.

- Está diseñado para ejecutar contenedores *stateless*

Para conocer todas las características podemos ver los detalles en la siguiente [liga](https://cloud.google.com/run#all-features)

 
¡Ahora vamos a hacer nuestro primer despliegue en Cloud Run!

## ¡Manos a la obra!

Para desplegar nuestro servicio en Cloud Run, vamos a desplegar una aplicación disponible en este [repositorio de Github](https://github.com/thewraven/cloud-run-example)


Para este tutorial vamos a usar una cuenta de Google Cloud (no te preocupes, está dentro de la cuota gratuita), Docker y algún cliente para consumir servicios HTTP

Como podemos ver en el archivo Dockerfile del proyecto, construye una aplicación en Go que comprime imágenes jpg, levantando un servidor HTTP escuchando en el puerto especificado de la variable de entorno `$PORT`. 

```docker
FROM golang:1.14-alpine as builder
WORKDIR /opt
COPY . /opt
RUN go build .

FROM alpine:3.11
RUN addgroup -S webgroup && adduser -S appgroup -G webgroup
USER appgroup
WORKDIR /opt
COPY --from=builder /opt/cloud-run-example .
ENV PORT
ENTRYPOINT [ "/opt/cloud-run-example" ]
```

Para desplegar el servicio vamos a acceder a Google Cloud, y usar un proyecto existente o crear uno nuevo.

Una vez tengamos un proyecto, vamos a abrir Cloud Run y configurar un nuevo servicio:

_Ubicamos la sección de Cloud Run_

![Ubicamos la sección de Cloud Run](https://dev-to-uploads.s3.amazonaws.com/i/7cohtvqzn342oe22lubs.jpg)

_Y creamos un nuevo servicio_

![Y creamos un nuevo servicio](https://dev-to-uploads.s3.amazonaws.com/i/e1j28o00q3al01pkk0g5.jpg)

_Ahora llenaremos el siguiente formulario_

![Ahora llenaremos el siguiente formulario](https://dev-to-uploads.s3.amazonaws.com/i/tf3a5npj9j99yynej5yh.jpg)

En el formulario ingresaremos el nombre *cloud-run-101*, y la región en la que se ejecutará el servicio. 

En la sección de autenticación eligiremos que el servicio permita peticiones sin autenticar. Al montar el servicio en producción deberíamos usar algún método de autenticación, ya sea integrado en el servicio o usando Cloud IAM.

_El ayudante de Cloud Run nos solicita una imagen de Docker, la cual subiremos a continuación_

![El ayudante de Cloud Run nos solicita una imagen de Docker, la cual subiremos a continuación](https://dev-to-uploads.s3.amazonaws.com/i/rmcbbs1eypdfb9jc9zrv.jpg)

Para desplegar la imagen que usaremos en nuestro repositorio privado de imágenes, abriremos una sesión de Cloud Shell y escribiremos el siguiente comando:

```bash
docker pull wraven/cloud-run-example:latest
```
Con el fin de descargar la imagen a nuestro repositorio de docker local. Lo que haremos después será re-etiquetar la imagen para subirla a nuestro repositorio privado. Por ello usaremos el id del proyecto, el cual obtendremos revisando el apartado de proyectos. 

_En esta sección encontraremos el id del proyecto_

![En esta sección encontraremos el id del proyecto](https://dev-to-uploads.s3.amazonaws.com/i/xu8ce6w8l9kw0wys3pfs.jpg)

Pondremos el id del proyecto como una variable en nuestra terminal, etiquetaremos de nuevo la imagen para subirla a nuestro repositorio privado.

```bash 
export PROJECT_ID=<tu-proyect-id>
docker tag wraven/cloud-run-example gcr.io/$PROJECT_ID/cloud-run-example:1.0
docker push gcr.io/$PROJECT_ID/cloud-run-example:1.0
```

_¡La imagen ya se puede utilizar en Cloud Run!_

![¡La imagen ya se puede utilizar en Cloud Run!](https://dev-to-uploads.s3.amazonaws.com/i/csps6f9cluw0ndrknong.jpg)

Vamos a ingresar el tag de la imagen en el asistente y después pulsaremos Crear

_Este es el último paso y habremos creado el servicio de Cloud Run_

![Este es el último paso y habremos creado el servicio de Cloud Run](https://dev-to-uploads.s3.amazonaws.com/i/5e4yggbhuraxe0n2vs5k.jpg)

Después de esto, veremos una pantalla donde se estará desplegando el servicio y nos dará una URL donde podremos consultarlo cuando esté disponible.

_Esta es la pantalla de información para nuestro servicio de Cloud Run_

![Esta es la pantalla de información para nuestro servicio de Cloud Run](https://dev-to-uploads.s3.amazonaws.com/i/rdd62kv4va4gxmbagmt4.jpg)


Estas son algunas propiedades relevantes sobre nuestro despliegue:

| Propiedad                     | Valor      | Descripción                                               |
|-------------------------------|------------|-----------------------------------------------------------|
| CPU asignada                  | 1          | vCPUs asignados al contenedor                             |
| Memoria asignada              | 256 MB     | Memoria RAM asignada                                      |
| Simultaneidad                 | 80         | Peticiones concurrentes que puede atender cada contenedor |
| Tiempo de espera de solicitud | 900 second | Tiempo máximo de respuesta                                |

También podremos ver la URL del servicio desplegado, donde ya podemos procesar peticiones, similar a esta:

> URL: https://cloud-run-example-bcexihr6qaff.a.run.app 
 
Si consultamos el servicio en un navegador, obtendremos una respuesta en JSON:

_Nuestro servicio ya está disponible y listo para usarse_

![Nuestro servicio ya está disponible y listo para usarse](https://dev-to-uploads.s3.amazonaws.com/i/kzwx726szet6cdqux3ph.jpg)

Ahora vamos a probar su funcionalidad. Para este servicio requerimos enviar una imagen JPEG y un parametro en 
la url _calidad_ con el valor (0-100) de la calidad en la que queremos obtener la respuesta.

_Probaremos usando [Postman](https://www.postman.com/) adjuntando una imagen a la petición POST._

![Probaremos usando Postman adjuntando una imagen a la petición POST]
(https://dev-to-uploads.s3.amazonaws.com/i/5s5ep7xjg0e801r05rni.jpg)

_Se especifica el párametro URL calidad con el porcentaje de calidad que se desea obtener. Al enviar la petición obtenemos una imagen con menor tamaño_

![Se especifica el párametro URL calidad](https://dev-to-uploads.s3.amazonaws.com/i/6lvcydsl2fzvwob9qu82.jpg)

Podemos probar con distintas imágenes y calidad para probar el funcionamiento del contenedor. Ahora, en la 
pestaña de registros podemos ver los logs del servicio.

_Los logs del servicio que se imprimen en la salida estándar se verán en este apartado_

![Los logs del servicio que se imprimen en la salida estándar se verán en este apartado](https://dev-to-uploads.s3.amazonaws.com/i/rcedlfutyt5cpoe712ur.jpg)

Vamos a desplegar otra versión del servicio para ajustar la configuración. Seleccionemos la opción
_Editar y desplegar una nueva revisión_.

_Ajustaremos el tiempo de respuesta a 300s, la memoria RAM a 128 MB y el máximo de 4 instancias_

![Ajustaremos el tiempo de respuesta a 300s, la memoria RAM a 128 MB y el máximo de 4 instancias](https://dev-to-uploads.s3.amazonaws.com/i/83rrcmpos5lm8fco4bld.jpg)

_Marcaremos *Servir esta revisión de inmediato* y pulsamos desplegar_

![Marcaremos Servir esta revisión de inmediato y pulsamos desplegar](https://dev-to-uploads.s3.amazonaws.com/i/m6d2069vhvpnnk2j4zgx.jpg)

Después de unos segundos que inicie el contenedor, podremos ver la información de la nueva revisión.

_Los detalles muestran la información de nuestra segunda revisión_

![Los detalles muestran la información de nuestra segunda revisión]
(https://dev-to-uploads.s3.amazonaws.com/i/v4ksnqpbtzt8p40bqpcn.jpg)

## Despliegues instantáneos con un sólo click

Después de hacer el proceso de despliegue manual, vamos a probar desplegando el mismo servicio usando un Cloud Run Button. 

Vamos al [repositorio de ejemplo](https://github.com/thewraven/cloud-run-example) y pulsemos sobre el botón _Run on Google Cloud_

_Usaremos [Run on Google Cloud](https://cloud.google.com/blog/products/serverless/introducing-cloud-run-button-click-to-deploy-your-git-repos-to-google-cloud) para desplegar el servicio de manera más sencilla_

![Usaremos Run on Google Cloud para desplegar el servicio de manera más sencilla](https://dev-to-uploads.s3.amazonaws.com/i/95dcdlaahdu8drkgx8rm.jpg)

_Nos mostrará un mensaje informativo sobre lo que sigue a continuación: Clonará el repositorio, construirá la imagen de Docker con la información del *Dockerfile*_

![Nos mostrará un mensaje informativo sobre lo que sigue a continuación: Clonará el repositorio, construirá la imagen de Docker con la información del *Dockerfile*](https://dev-to-uploads.s3.amazonaws.com/i/bxiyw89puberrxxd5nv5.jpg)

Ahora en una ventana de Cloud Shell, se mostrará el detalle del despliegue con algunas preguntas

_Primero se revisa el proyecto de Google Cloud donde se construirá el servicio_

![Primero se revisa el proyecto de Google Cloud donde se construirá el servicio](https://dev-to-uploads.s3.amazonaws.com/i/p1ux315vxc4fbcgw4o8k.jpg)

_Se construye la imagen de Docker dentro de Cloud Shell_
 
![Se construye la imagen de Docker dentro de Cloud Shell](https://dev-to-uploads.s3.amazonaws.com/i/wizgl1t1pnajuv0fcfnr.jpg)

_La sube al registro de Docker privado e inicia el despliegue. Veremos el detalle del servicio, la URL desde la cual es accesible y el panel de administración para revisar los detalles_

![Se inicia el despliegue](https://dev-to-uploads.s3.amazonaws.com/i/rayvvx0qkq01xg9gcv5f.jpg)

Si ejecutamos el servicio a esta nueva URL veremos que también funciona

_Gracias a Cloud Run Button en el repositorio de Github y el Dockerfile configurado en él, fue más rápido desplegar el mismo servicio_

![Gracias a Cloud Run Button fue más rápido desplegar el mismo servicio](https://dev-to-uploads.s3.amazonaws.com/i/z3v8xojx2p99zbo8ik4s.jpg)

## Limpiando todo

Volvamos a la sección de Cloud Run para eliminar el servicio que creamos,
después abriremos una terminal de Cloud Shell para borrar las imágenes construidas de nuestro registro privado.

_Eliminamos el servicio desde Cloud Run, nos pedirá una confirmación, y Aceptamos pulsando *Eliminar*_

![Eliminamos el servicio desde Cloud Run, nos pedirá una confirmación, y Aceptamos pulsando Eliminar](https://dev-to-uploads.s3.amazonaws.com/i/3f9og5lbthazqfluy2h1.jpg)

_Vamos al Shell para eliminar las imágenes que existen en el repositorio privado_

![Vamos al Shell para eliminar las imágenes que existen en el repositorio privado](https://dev-to-uploads.s3.amazonaws.com/i/tgabwq4dwj6dft0fmquk.jpg)

El comando para eliminar las imágenes es el siguiente:

```bash
gcloud container images delete gcr.io/$PROJECT_ID/cloud-run-example
```

¡Espero te haya gustado la publicación! Comparte tus dudas o comentarios aquí :)


## Para más información

Consulta las ligas oficiales de Cloud Run y algunos ejemplos prácticos:

* [Documentación](https://cloud.google.com/run/docs)
* [Codelabs (en inglés)](https://codelabs.developers.google.com/codelabs/cloud-run-deploy/index.html?index=..%2F..index#0)
* [Implementa en Google Cloud](https://cloud.google.com/cloud-build/docs/deploying-builds/deploy-cloud-run?hl=es-419)