1. Introducción
Descripción general
Para proteger el tráfico de red de sus servicios y aplicaciones, muchas organizaciones usan una red de nube privada virtual (VPC) en Google Cloud con controles perimetrales para evitar el robo de datos. Una red de VPC es una versión virtual de una red física que se implementa en la red de producción de Google. Una red de VPC proporciona conectividad para tus instancias de máquinas virtuales (VM) de Compute Engine, ofrece balanceadores de cargas de red de transferencia interna nativos y sistemas proxy para balanceadores de cargas de aplicaciones internos, se conecta a redes locales a través de túneles de Cloud VPN y adjuntos de VLAN para Cloud Interconnect, y distribuye el tráfico de los balanceadores de cargas externos de Google Cloud a los backends.
A diferencia de las VM, los servicios de Cloud Run no están asociados a ninguna red de VPC en particular de forma predeterminada. En este codelab, se muestra cómo cambiar la configuración de entrada (conexiones entrantes) de modo que solo el tráfico proveniente de una VPC pueda acceder a un servicio de Cloud Run (p.ej., un servicio de backend). Además, en este codelab, se muestra cómo hacer que un segundo servicio (p.ej., un servicio de frontend) acceda al servicio de backend de Cloud Run a través de una VPC y también cómo seguir teniendo acceso público a Internet.
En este ejemplo, el servicio de backend de Cloud Run muestra hello world. El servicio de frontend de Cloud Run proporciona un campo de entrada en la IU para recopilar una URL. Luego, el servicio de frontend realiza una solicitud GET a esa URL (p.ej., el servicio de backend), lo que hace que sea una solicitud de servicio a servicio (en lugar de una solicitud de navegador a servicio). Cuando el servicio de frontend puede llegar al backend de forma correcta, el mensaje hello world se muestra en el navegador. Luego, verás cómo puedes realizar una llamada a https://curlmyip.org para recuperar la dirección IP de tu servicio de frontend.
Qué aprenderás
- Cómo permitir solo el tráfico de una VPC a tu servicio de Cloud Run
- Cómo configurar la salida en un servicio de Cloud Run (p. ej., frontend) para comunicarse con un servicio de Cloud Run solo de entrada interna (p. ej., backend), mientras se mantiene el acceso público a Internet para el servicio de frontend
2. Configuración y requisitos
Requisitos previos
- Accediste a la consola de Cloud.
- Ya implementaste una función de 2ª gen. Por ejemplo, puedes seguir la guía de inicio rápido para implementar una función de Cloud de 2ª gen. 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 en la que se describe qué es. Si viste una pantalla intermedia, haz clic en Continuar.

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

Esta máquina virtual se carga con todas las herramientas de desarrollo necesarias. 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 con un navegador.
Una vez que te conectes a Cloud Shell, deberías ver que ya te autenticaste y que el proyecto ya se configuró con el ID de tu 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`
- En Cloud Shell, ejecuta el siguiente comando para confirmar que el comando gcloud conoce tu proyecto:
gcloud config list project
Resultado del comando
[core] project = <PROJECT_ID>
De lo contrario, puede configurarlo con este comando:
gcloud config set project <PROJECT_ID>
Resultado del comando
Updated property [core/project].
3. Crea los servicios de Cloud Run
Configura variables de entorno
Puedes configurar variables de entorno que se usarán en este codelab.
PROJECT_ID=<YOUR_PROJECT_ID> REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend-with-internet BACKEND=backend SUBNET_NAME=default
Crea el servicio de backend de Cloud Run
Primero, crea un directorio para el código fuente y cd en ese directorio.
mkdir -p egress-private-codelab/frontend-w-internet egress-private-codelab/backend && cd egress-private-codelab/backend
Luego, crea un archivo `package.json`` con el siguiente contenido:
{
"name": "backend-service",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.18.1"
}
}
A continuación, crea un archivo fuente index.js con el siguiente contenido. Este archivo contiene el punto de entrada del servicio y la lógica principal de la app.
const express = require('express');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.get('/', function (req, res) {
res.send("hello world");
});
const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
console.log(`helloworld: listening on port ${port}`);
});
Por último, implementa el servicio de Cloud Run con el siguiente comando.
gcloud run deploy $BACKEND --source . --allow-unauthenticated --region $REGION
Crea el servicio de frontend de Cloud Run
Navega al directorio de frontend.
cd ../frontend-w-internet
Luego, crea un archivo package.json con el siguiente contenido:
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.6.6",
"express": "^4.18.2",
"htmx.org": "^1.9.10"
}
}
A continuación, crea un archivo fuente index.js con el siguiente contenido. Este archivo contiene el punto de entrada del servicio y la lógica principal de la app.
const express = require("express");
const app = express();
const port = 8080;
const path = require('path');
const axios = require('axios');
// serve static content (index.html) using
// built-in middleware function in Express
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true }));
// this endpoint receives a URL in the post body
// and then makes a get request to that URL
// results are sent back to the caller
app.post('/callService', async (req, res) => {
const url = req.body.url;
let message = "";
try {
console.log("url: ", url);
const response = await axios.get(url);
message = response.data;
} catch (error) {
message = error.message;
console.error(error.message);
}
res.send(`
${message}
<p>
</p>
`);
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Crea un directorio público para el archivo index.html.
mkdir public touch public/index.html
Y actualiza el index.html para que contenga lo siguiente:
<html>
<script
src="https://unpkg.com/htmx.org@1.9.10"
integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
crossorigin="anonymous"
></script>
<body>
<div style="margin-top: 100px; margin-left: 100px">
<h1>I'm the Request Tester service on the Internet</h1>
<form hx-trigger="submit" hx-post="/callService" hx-target="#zen">
<label for="url"> URL:</label>
<input
style="width: 308px"
type="text"
id="url"
name="url"
placeholder="The backend service URL"
required
/>
<button hx-indicator="#loading" type="submit">Submit</button>
<p></p>
<span class="htmx-indicator" id="loading"> Loading... </span>
<div id="zen" style="white-space: pre-wrap"></div>
<p></p>
</form>
</div>
</body>
</html>
Por último, implementa el servicio de Cloud Run con el siguiente comando.
gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION
Llama al servicio de backend
En esta sección, verificarás que implementaste correctamente dos servicios de Cloud Run.
Abre la URL del servicio de frontend en tu navegador web, p. ej., https://frontend-your-hash-uc.a.run.app/.
En el cuadro de texto, ingresa la URL del servicio de backend. Ten en cuenta que esta solicitud se enruta desde la instancia de Cloud Run de frontend al servicio de Cloud Run de backend, y no desde tu navegador.
Verás "hello world".
4. Configura el servicio de backend solo para la entrada interna
Puedes ejecutar el siguiente comando de gcloud para incorporar un servicio de Cloud Run a tu red privada.
gcloud run services update $BACKEND --ingress internal --region $REGION
Si intentaras llamar al servicio de backend desde el servicio de frontend, recibirías un error 404. La conexión saliente (o salida) del servicio de frontend de Cloud Run se dirige primero a Internet, por lo que Google Cloud no conoce el origen de la solicitud.
5. Configura el servicio de frontend para acceder a la VPC
En esta sección, configurarás tu servicio de frontend de Cloud Run para que se comunique con tu servicio de backend a través de una VPC.
Para ello, deberás agregar la salida de VPC directa a tu servicio de frontend de Cloud Run para asegurarte de que pueda llegar a las direcciones IP internas en la red de VPC. Luego, configurarás la salida de modo que solo las solicitudes a IPs privadas se enruten a la VPC. Esta configuración permitirá que tu frontend siga llegando a Internet pública. Puedes obtener más información en la documentación sobre cómo recibir solicitudes de otros servicios de Cloud Run.
Configura la salida de VPC directa
Primero, ejecuta este comando para usar la salida de VPC directa en tu servicio de frontend:
gcloud beta run services update $FRONTEND \ --network=$SUBNET_NAME \ --subnet=$SUBNET_NAME \ --vpc-egress=private-ranges-only \ --region=$REGION
Ahora puedes confirmar que tu servicio de frontend tiene acceso a la VPC:
gcloud beta run services describe $FRONTEND \ --region=$REGION
Deberías ver un resultado similar al siguiente:
VPC access:
Network: default
Subnet: default
Egress: private-ranges-only
Habilita el Acceso privado a Google
A continuación, ejecuta el siguiente comando para habilitar el Acceso privado a Google en la subred:
gcloud compute networks subnets update $SUBNET_NAME \ --region=$REGION \ --enable-private-ip-google-access
Puedes verificar que el Acceso privado a Google se habilitó con este comando:
gcloud compute networks subnets describe $SUBNET_NAME \ --region=$REGION \ --format="get(privateIpGoogleAccess)"
Crea una zona de Cloud DNS para las URLs de run.app
Por último, crea una zona de Cloud DNS para las URLs de run.app de modo que Google Cloud pueda tratarlas como direcciones IP internas.
En un paso anterior, configuraste la salida de VPC directa solo para rangos privados. Esto significa que las conexiones salientes de tu servicio de frontend solo irán a la red de VPC si el destino es una IP interna. Sin embargo, tu servicio de backend usa una URL de run.app que se resuelve en una IP pública.
En este paso, crearás una zona de Cloud DNS para que las URLs de run.app se resuelvan en los rangos de direcciones IP de private.googleapis.com, que se reconocen como direcciones IP internas. Ahora, cualquier solicitud a estos rangos se enrutará a través de tu red de VPC.
Para ello, haz lo siguiente: https://cloud.google.com/run/docs/securing/private-networking#from-other-services
# do not include the https:// in your DNS Name # for example: backend-<hash>-uc.a.run.app DNS_NAME=<your backend service URL without the https://> gcloud dns --project=$PROJECT_ID managed-zones create codelab-backend-service \ --description="" \ --dns-name="a.run.app." \ --visibility="private" \ --networks=$SUBNET_NAME gcloud dns --project=$PROJECT_ID record-sets create $DNS_NAME. \ --zone="codelab-backend-service" \ --type="A" \ --ttl="60" \ --rrdatas="199.36.153.8,199.36.153.9,199.36.153.10,199.36.153.11"
Ahora, cuando intentes llegar al servicio de backend de tu sitio web, verás que se muestra "hello world".
Y cuando intentes llegar a Internet con https://curlmyip.org/, verás tu dirección IP.
6. Solución de problemas
Estos son algunos mensajes de error posibles que puedes encontrar si la configuración no se realizó correctamente.
- Si recibes un error
getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.app, asegúrate de no haber agregado "https://" al registro A de DNS. - Si recibes un error 404 cuando intentas acceder al backend después de configurar la zona, puedes esperar a que venza la caché en el registro global de run.app (p. ej., 6 horas) o puedes crear una revisión nueva (y, por lo tanto, borrar la caché) ejecutando el siguiente comando:
gcloud beta run services update $FRONTEND --network=$SUBNET_NAME --subnet=$SUBNET_NAME --vpc-egress=private-ranges-only --region=$REGION.
7. ¡Felicitaciones!
Felicitaciones por completar el codelab.
Te recomendamos que revises la documentación sobre redes privadas en Cloud Run.
Temas abordados
- Cómo permitir solo el tráfico de una VPC a tu servicio de Cloud Run
- Cómo configurar la salida en un servicio de Cloud Run (p. ej., frontend) para comunicarse con un servicio de Cloud Run solo de entrada interna (p. ej., backend), mientras se mantiene el acceso público a Internet para el servicio de frontend
8. Limpia
Para evitar cargos involuntarios (por ejemplo, si este servicio de Cloud Run se invoca de forma involuntaria más veces que tu asignación mensual de invocación de Cloud Run en el nivel gratuito), puedes borrar el servicio de Cloud Run o el proyecto que creaste en el paso 2.
Para borrar los servicios de Cloud Run, ve a la consola de Cloud Run en https://console.cloud.google.com/functions/ y borra los servicios $FRONTEND y $BACKEND que creaste en este codelab.
Si decides borrar todo el proyecto, 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.