1. Descripción general
Introducción
En este codelab, aprenderás a implementar un servicio de Cloud Run que usa varios contenedores. Crearás una app de node.js que se usará como el contenedor de entrada de Cloud Run y una app de node.js adicional que se usará como archivo adicional.
Descripción técnica general
Cuando se usan varios contenedores en una instancia de Cloud Run, se usa uno como el principal para la entrada web. Los contenedores adicionales se denominan sidecars.
Existen dos maneras en las que varios contenedores se comunican entre sí:
- Los contenedores comparten la interfaz de red localhost, por lo que todos los contenedores pueden escuchar un puerto, p.ej., localhost:port.
- También puedes usar volúmenes en la memoria y activarlos en los contenedores para compartir archivos.
Casos de uso
Dado que todos los contenedores dentro de la instancia de Cloud Run comparten la interfaz de red localhost, puedes usar un archivo adicional frente a tu contenedor principal para enviar solicitudes de proxy. Esos proxies pueden proporcionar una capa adicional de abstracción para un flujo más eficiente de tráfico a la aplicación entre el cliente y los servidores mediante la interceptación de solicitudes y su reenvío al endpoint correspondiente. A modo de ejemplo, puede usar la imagen oficial de Nginx de DockerHub (como se muestra aquí).
Dado que varios contenedores se pueden comunicar compartiendo archivos a través de volúmenes compartidos, debes agregar varias aplicaciones de archivo adicional a tu servicio. Por ejemplo, puedes instrumentar tu servicio de Cloud Run para usar agentes personalizados, como OpenTelemetry para exportar registros, métricas y seguimientos (ejemplo de OpenTelemetry). Otro ejemplo es usar una conexión de archivo adicional a una base de datos PostgreSQL de Cloud Spanner (ejemplo de Cloud Spanner Postgress).
Ejemplos de este codelab
En este codelab, primero implementarás un servicio de Cloud Run en el que su contenedor de entrada se comunique con un archivo adicional a través de un puerto localhost. Luego, actualizarás el contenedor de entrada y el archivo adicional para compartir un archivo mediante la activación de volumen.
Qué aprenderás
- Cómo crear un contenedor que use un archivo adicional
- Cómo un contenedor de entrada puede comunicarse con un archivo adicional mediante localhost
- Cómo un contenedor de entrada y un archivo adicional pueden compartir un archivo a través de un volumen activado
2. Configuración y requisitos
Requisitos previos
- Accediste a la consola de Cloud.
- Ya implementaste un servicio de Cloud Run. Por ejemplo, puedes seguir la guía de inicio rápido para implementar un servicio web desde el código fuente para comenzar.
Activar Cloud Shell
- En la consola de Cloud, haz clic en Activar Cloud Shell.
Si es la primera vez que inicias Cloud Shell, verás una pantalla intermedia que describe en qué consiste. Si apareció una pantalla intermedia, haz clic en Continuar.
El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.
Esta máquina virtual está cargada con todas las herramientas de desarrollo necesarias. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que mejora considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer con un navegador.
Una vez que te conectes a Cloud Shell, deberías ver que estás autenticado y que el proyecto está configurado con tu ID del proyecto.
- En Cloud Shell, ejecuta el siguiente comando para confirmar que tienes la autenticación:
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`
- 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].
3. Crea la app de Ingress
Configura las variables de entorno
En este codelab, crearás algunas variables de entorno para mejorar la legibilidad de los comandos de gcloud
que se usan en este codelab.
REGION=<YOUR-REGION> PROJECT_ID=<YOUR-PROJECT-ID> SERVICE_NAME=sidecar-codelab REPO_NAME=sidecar-codelab
Crea un repositorio de ArtifactRegistry para guardar las imágenes de contenedor
Puedes crear un repositorio en Artifact Registry para almacenar las imágenes de contenedor para este codelab.
gcloud artifacts repositories create $REPO_NAME --repository-format=docker \ --location=$REGION --description="sidecar codelab"
Luego, crea un archivo package.json
con el siguiente contenido:
{ "name": "sidecar-codelab", "version": "1.0.0", "private": true, "description": "demonstrates how to use sidecars in cloud run", "main": "index.js", "author": "Google LLC", "license": "Apache-2.0", "scripts": { "start": "node ingress.js" }, "dependencies": { "axios": "^1.6.2", "express": "^4.18.2" } }
Ahora, crea un archivo llamado ingress.js
con el siguiente contenido:
const express = require('express'); const app = express(); const axios = require("axios"); app.get('/', async (req, res) => { let response = await axios.get("http://localhost:5000"); res.send("The sidecar says: " + response.data); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`Ingress container listening on port ${port}`); });
Crea un Dockerfile para el contenedor de Ingress
FROM node:20.10.0-slim WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --production # Copy local code to the container image. COPY . . # Run the web service on container startup. ENV PORT=8080 CMD [ "npm", "start" ]
Y crea un archivo ``.dockerignore` para el contenedor de Ingress.
# Exclude locally installed dependencies node_modules/ # Exclude "build-time" ignore files. .dockerignore .gcloudignore # Exclude git history and configuration. .gitignore
Ahora puedes compilar la imagen para tu contenedor de Ingress ejecutando el siguiente comando:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest
4. Crea la app de sidecar
En esta sección, crearás una segunda app de node.js que se usará como archivo adicional en el servicio de Cloud Run.
Navega al directorio de sidecar.
cd ../sidecar
Crea un archivo package.json
con el siguiente contenido:
{ "name": "sidecar-codelab", "version": "1.0.0", "private": true, "description": "demonstrates how to use sidecars in cloud run", "main": "index.js", "author": "Google LLC", "license": "Apache-2.0", "scripts": { "start": "node sidecar.js" }, "dependencies": { "axios": "^1.6.2", "express": "^4.18.2" } }
Ahora, crea un archivo llamado sidecar.js
con el siguiente contenido:
const express = require('express'); const app = express(); app.get('/', async (req, res) => { res.send("Hello ingress container! I'm the sidecar."); }); const port = parseInt(process.env.PORT || 5000); app.listen(port, () => { console.log(`Sidecar container listening on port ${port}`); });
Crea un Dockerfile para el contenedor del archivo adicional
FROM node:20.10.0-slim WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --production # Copy local code to the container image. COPY . . # Run the web service on container startup. ENV PORT=5000 CMD [ "npm", "start" ]
Y crea un archivo ``.dockerignore` para el contenedor del archivo adicional.
# Exclude locally installed dependencies node_modules/ # Exclude "build-time" ignore files. .dockerignore .gcloudignore # Exclude git history and configuration. .gitignore
Ahora puedes compilar la imagen para tu contenedor de Ingress ejecutando el siguiente comando:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest
Implementa el servicio de Cloud Run
Implementarás el servicio de Cloud Run con un archivo yaml.
Navega al directorio superior.
cd ..
Crea un archivo sidecar-codelab.yaml
con el siguiente contenido:
apiVersion: serving.knative.dev/v1 kind: Service metadata: annotations: name: sidecar-codelab labels: cloud.googleapis.com/location: "<YOUR_REGION>" spec: template: spec: containers: - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest" ports: - containerPort: 8080 - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest" env: - name: PORT value: "5000"
Luego, implementa el servicio con el siguiente comando. Debes usar gcloud beta porque las activaciones de volúmenes se encuentran en versión preliminar pública.
gcloud beta run services replace sidecar-codelab.yaml
Una vez implementada, guarda la URL de servicio en una variable de entorno.
SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --platform managed --region $REGION --format 'value(status.url)')
5. Llama al servicio de Cloud Run
Ahora puedes llamar a tu servicio proporcionando tu token de identidad.
curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}
Tus resultados deberían ser similares al resultado de ejemplo a continuación:
The sidecar says: Hello ingress container! I'm the sidecar.
6. Cómo compartir un archivo mediante la activación de volumen
En esta sección, actualizarás los contenedores para compartir un archivo mediante la activación de volumen. En este ejemplo, el contenedor de Ingress escribirá en un archivo en un volumen compartido. El archivo adicional leerá el archivo y mostrará su contenido de vuelta en el contenedor de Ingress.
Primero, actualizarás el código del contenedor de entrada. Navega al directorio ingress.
cd ../ingress
Luego, reemplaza el contenido del archivo ingress.js
por lo siguiente:
const express = require('express'); const app = express(); const fs = require('fs'); const axios = require("axios"); const filename = "test.txt" let path = "/my-volume-mount"; app.use(path, express.static(path)); try { fs.writeFileSync(`${path}/${filename}`, "The ingress container created this file."); } catch (err) { console.error(err); } app.get('/', async (req, res) => { let response = await axios.get("http://localhost:5000"); res.send("The sidecar says: " + response.data); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`Ingress container listening on port ${port}`); });
Ejecuta el siguiente comando para compilar la imagen nueva para tu contenedor de Ingress:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest
Ahora, navega al directorio de sidecar:
cd ../sidecar
Además, actualiza sidecar.js
con el siguiente contenido:
const express = require('express'); const app = express(); const fs = require('fs'); const filename = "test.txt" let path = "/my-volume-mount"; app.use(path, express.static(path)); async function readFile() { try { return await fs.readFileSync(`${path}/${filename}`, { encoding: 'utf8' }); } catch (err) { console.log(err); } } app.get('/', async (req, res) => { let contents = await readFile(); res.send(contents); }); const port = parseInt(process.env.PORT || 5000); app.listen(port, () => { console.log(`Sidecar container listening on port ${port}`); });
Ejecuta el siguiente comando para compilar la imagen nueva para el contenedor de archivo adicional:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest
Actualiza sidecar-codelab.yaml
con lo siguiente para compartir un volumen:
apiVersion: serving.knative.dev/v1 kind: Service metadata: annotations: name: sidecar-codelab labels: cloud.googleapis.com/location: "<YOUR_REGION>" spec: template: spec: containers: - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest" ports: - containerPort: 8080 volumeMounts: - mountPath: /my-volume-mount name: in-memory-1 - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest" env: - name: PORT value: "5000" volumeMounts: - mountPath: /my-volume-mount name: in-memory-1 volumes: - emptyDir: medium: Memory name: in-memory-1
Implementa el archivo sidecar-codelab.yaml
actualizado
gcloud beta run services replace sidecar-codelab.yaml
Ahora puedes llamar a tu servicio proporcionando tu token de identidad.
curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}
Tus resultados deberían ser similares al resultado de ejemplo a continuación:
The sidecar says: the ingress container created this file.
7. ¡Felicitaciones!
¡Felicitaciones por completar el codelab!
Recomendamos revisar la documentación en Cloud Run, específicamente implementar varios contenedores y usar activaciones de volúmenes en memoria.
Temas abordados
- Cómo crear un contenedor que use un archivo adicional
- Cómo un contenedor de entrada puede comunicarse con un archivo adicional mediante localhost
- Cómo un contenedor de entrada y un archivo adicional pueden compartir un volumen activado
8. Limpia
Para evitar cargos accidentales (por ejemplo, si esta Cloud Function se invoca de forma involuntaria más veces que tu asignación de invocación mensual de Cloud Run en el nivel gratuito), puedes borrar el servicio de Cloud Run o borrar el proyecto que creaste en el paso 2.
Para borrar la Cloud Function, ve a la consola de Cloud Function en https://console.cloud.google.com/run/ y borra el servicio sidecar-codelab
(o $SERVICE_NAME si usaste otro nombre).
Si decides borrar el proyecto completo, puedes ir a https://console.cloud.google.com/cloud-resource-manager, seleccionar el proyecto que creaste en el paso 2 y elegir Borrar. Si borras el proyecto, deberás cambiar los proyectos en tu SDK de Cloud. Para ver la lista de todos los proyectos disponibles, ejecuta gcloud projects list
.