Registra direcciones IP privadas para grupos de trabajadores con Cloud DNS

En este instructivo, se describe cómo registrar la dirección IP privada de una instancia del grupo de trabajadores de Cloud Run en una zona administrada de Cloud DNS. En este instructivo, usarás una secuencia de comandos de inicio para detectar de forma dinámica la IP de la instancia a través del servidor de metadatos y crearás una aplicación de Node.js para controlar el tráfico de entrada directamente dentro de tu red de VPC.

Objetivos

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.

Es posible que los usuarios nuevos de Google Cloud cumplan con los requisitos para acceder a una prueba gratuita.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud . Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Habilita las APIs de Cloud DNS, Cloud Run, Compute Engine, Artifact Registry y Cloud Build.

    Roles necesarios para habilitar las APIs

    Para habilitar las APIs, necesitas el rol de IAM de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin), que contiene el permiso serviceusage.services.enable. Obtén más información para otorgar roles.

    Habilitar las API

  7. Instala y, luego, inicializa gcloud CLI.
  8. Actualiza los componentes, como se indica a continuación:
    gcloud components update
  9. Ejecuta el siguiente comando para configurar el ID del proyecto:
    gcloud config set project PROJECT_ID
    Reemplaza PROJECT_ID por el ID de tu proyecto Google Cloud .

Roles obligatorios

Si quieres obtener los permisos que necesitas para completar el instructivo, pídele a tu administrador que te otorgue los siguientes roles de IAM en tu proyecto:

Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

Crea una cuenta de servicio personalizada

Crea una cuenta de servicio personalizada con los permisos mínimos requeridos para registrar registros DNS. Para configurar la cuenta de servicio, haz lo siguiente:

  1. Ejecuta el siguiente comando para crear una cuenta de servicio:

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="DNS Worker Pool Service Account"

    Reemplaza SERVICE_ACCOUNT_NAME por un nombre para tu cuenta de servicio personalizada, por ejemplo, dns-worker-sa.

  2. Otorga el rol de administrador de Cloud DNS a la cuenta de servicio:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member="serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/dns.admin"

Crear una zona de Cloud DNS

Crea una zona privada administrada por Cloud DNS llamada test-wp para registrar la IP de la instancia de tu grupo de trabajadores.

gcloud dns managed-zones create test-wp --description="new DNS zone for worker pools"  --dns-name="workerpools.example.com."  --visibility="private" --networks=default

Crea una aplicación de Node.js

Crea una aplicación de Node.js que recupere la dirección IP de la instancia del grupo de trabajadores con el servidor de metadatos y, luego, la registre en Cloud DNS.

  1. Crea una carpeta llamada worker y cambia el directorio a ella:

    mkdir worker
    cd worker
    
  2. Crea un archivo llamado setup_dns.sh y agrega la siguiente secuencia de comandos que se ejecuta cuando se inicia la instancia del grupo de trabajadores. Esta secuencia de comandos usa el nombre de host de la instancia para generar el nombre del registro DNS. Si hay más de una instancia, varias instancias pueden usar el mismo nombre de host, lo que genera la creación de registros de DNS superpuestos.

    #!/bin/bash
    
    # --- Variables ---
    # The name of your Cloud DNS managed zone.
    ZONE_NAME="test-wp"
    # The base domain suffix for the DNS entry. Use the part *after* the hostname.
    # For example, for "testinstance.workerpools.example.com.", the suffix is ".workerpools.example.com."
    DNS_SUFFIX=".workerpools.example.com."
    # The Time-To-Live (TTL) in seconds.
    TTL="300"
    # The record type (A for IPv4).
    RECORD_TYPE="A"
    # -----------------
    
    # 1. Dynamically generate DNS_NAME
    # Get the simple hostname (e.g., "testinstance") and append the defined suffix.
    # We use 'hostname -s' to get the short hostname.
    SHORT_HOSTNAME=$(hostname -s)
    DNS_NAME="${SHORT_HOSTNAME}${DNS_SUFFIX}"
    
    # 2. Dynamically assign NEW_IP
    # Get the IP address from metadata server using predefined key.
    NEW_IP=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip" -H "Metadata-Flavor: Google")
    
    # --- Input Validation ---
    if [ -z "$NEW_IP" ]; then
        echo "❌ ERROR: Could not obtain a valid IP address from metadata server. Aborting."
        exit 1
    fi
    
    echo "Starting DNS record update for ${DNS_NAME} in zone ${ZONE_NAME}..."
    echo "New IP detected on this instance: ${NEW_IP}"
    
    # 3. Get the current existing IP address (if any)
    # This is required to know what to put in the --rrdatas for the delete command.
    EXISTING_IP=$(gcloud dns record-sets list \
        --zone="${ZONE_NAME}" \
        --name="${DNS_NAME}" \
        --type="${RECORD_TYPE}" \
        --format="value(rrdatas[0])" 2>/dev/null)
    
    # --- Conditional Deletion/Skip Check ---
    if [ -n "$EXISTING_IP" ] && [ "$EXISTING_IP" != "$NEW_IP" ]; then
        echo "Found existing IP: ${EXISTING_IP}. It is different from the new IP."
    
        # Delete the existing record
        echo "Deleting old record..."
        gcloud dns record-sets delete "${DNS_NAME}" \
            --zone="${ZONE_NAME}" \
            --type="${RECORD_TYPE}" \
            --quiet
    
        if [ $? -ne 0 ]; then
            echo "❌ ERROR: Failed to delete existing record. Aborting."
            exit 1
        fi
    elif [ -n "$EXISTING_IP" ] && [ "$EXISTING_IP" == "$NEW_IP" ]; then
        echo "Existing IP (${EXISTING_IP}) matches the new IP. Skipping update."
        exit 0
    else
        echo "No existing record found for ${DNS_NAME}. Proceeding with creation."
    fi
    # ----------------------------------------
    
    # 4. Add the new record
    echo "Creating new record with IP: ${NEW_IP}..."
    gcloud dns record-sets create "${DNS_NAME}" \
      --zone="${ZONE_NAME}" \
      --type="${RECORD_TYPE}" \
      --ttl="${TTL}" \
      --rrdatas="${NEW_IP}"
    
    # Final status check
    if [ $? -eq 0 ]; then
        echo "✅ Successfully created/updated DNS record for ${DNS_NAME} to ${NEW_IP}."
    else
        echo "❌ ERROR: Failed to create the new DNS record."
        exit 1
    fi
    
  3. Crea un archivo server.js con el siguiente código para controlar el ingreso de la dirección IP privada:

    // server.js
    
    // 1. Import the built-in 'http' module
    console.log("hello from worker pool")
    const http = require('http');
    
    // Define the port the server will listen on
    const PORT = 3000;
    
    // 2. Create the server instance
    const server = http.createServer((req, res) => {
      // Set the response HTTP header with status and type of content
      res.writeHead(200, {'Content-Type': 'text/plain'});
      // Write the response body
      res.end('Hello World!\n');
    });
    
    // 3. Start the server and listen on the specified port
    server.listen(PORT, () => {
      console.log(`Server running at http://localhost:${PORT}/`);
    });
    
  4. Crea una secuencia de comandos start.sh con el siguiente código para realizar la configuración de DNS primero, antes de ejecutar tu aplicación de Node.js:

    #!/bin/bash
    set -e
    
    # 1. Execute the setup script
    echo "Running setup_dns.sh..."
    /app/setup_dns.sh
    
    # 2. Run the main application
    echo "Starting server.js..."
    exec node /app/server.js
    
  5. Crea el siguiente Dockerfile para empaquetar la aplicación en una imagen:

    # Choose a base image. This image includes gcloud, kubectl, etc.
    FROM google/cloud-sdk:latest
    
    # Install Node.js on top of the Cloud SDK image.
    RUN apt-get update && \
        apt-get install -y curl && \
        curl -sL https://deb.nodesource.com/setup_lts.x | bash - && \
        apt-get install -y nodejs && \
        # Clean up to reduce image size
        apt-get clean && \
        rm -rf /var/lib/apt/lists/*
    
    # Set the working directory inside the container.
    WORKDIR /app
    
    # Copy the application and scripts into the container.
    COPY setup_dns.sh .
    COPY server.js .
    COPY start.sh .
    
    # Make both scripts executable.
    RUN chmod +x setup_dns.sh start.sh
    
    # Define the entrypoint and default command.
    ENTRYPOINT ["/app/start.sh"]
    CMD []
    

Implementa un grupo de trabajadores con entrada de VPC directa

Implementa un grupo de trabajadores llamado test-cli-dns y adjúntalo a una red de VPC.

gcloud beta run worker-pools deploy test-cli-dns \
  --network default \
  --subnet default \
  --region us-central1 \
  --source . \
  --service-account SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \
  --project PROJECT_ID

Reemplaza PROJECT_ID por el ID de tu proyecto Google Cloud y SERVICE_ACCOUNT_NAME por el nombre de la cuenta de servicio que creaste.

Prueba tu aplicación

Los grupos de trabajadores de Cloud Run con entrada de VPC directa están diseñados para el tráfico interno únicamente. No tienen una IP pública. Para verificar la funcionalidad de entrada, sigue estos pasos para ejecutar una solicitud con curl desde una VM de Compute Engine alojada en la misma red de VPC y subred:

  1. Crea una VM de prueba en la misma red y región que tu grupo de trabajadores:

     gcloud compute instances create wp-test-vm \
         --zone=us-central1-a \
         --network=default \
         --subnet=default
    
  2. Conéctate a la VM de prueba a través de SSH ejecutando el siguiente comando:

     gcloud compute ssh wp-test-vm --zone=us-central1-a
    
  3. Desde la terminal de la VM, invoca tu servicio en la dirección IP privada de la instancia del grupo de trabajadores registrada en Cloud DNS:

    curl http://localhost.workerpools.example.com:3000

    Deberías ver el siguiente resultado:

    Hello World!

¡Listo! Configuraste correctamente tu grupo de trabajadores de Cloud Run con la entrada directa a la VPC a través de una dirección IP privada y Cloud DNS.

Realiza una limpieza

Para evitar cargos adicionales en tu cuenta de Google Cloud , borra todos los recursos que implementaste con este instructivo.

Borra el proyecto

Si creaste un proyecto nuevo para este instructivo, bórralo. Si usaste un proyecto existente y necesitas conservarlo sin los cambios que agregaste en este instructivo, borra los recursos que creaste para el instructivo.

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, sigue estos pasos:

  1. En la Google Cloud consola, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Elimina recursos de instructivos

  1. Borra el servicio de Cloud Run que implementaste en este instructivo. Los servicios de Cloud Run no generan costos hasta que reciben solicitudes.

    Para borrar tu servicio de Cloud Run, ejecuta el siguiente comando:

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME por el nombre del servicio

    También puedes borrar los servicios de Cloud Run desde la consola deGoogle Cloud .

  2. Quita la configuración de región predeterminada de gcloud que agregaste durante la configuración del instructivo:

     gcloud config unset run/region
    
  3. Quita la configuración del proyecto:

     gcloud config unset project
    
  4. Borra otros Google Cloud recursos que creaste en este instructivo:

¿Qué sigue?