Registrar endereços IP particulares para pools de workers usando o Cloud DNS

Neste tutorial, descrevemos como registrar o endereço IP particular de uma instância de pool de workers do Cloud Run em uma zona gerenciada do Cloud DNS. Neste tutorial, você vai usar um script de inicialização para detectar dinamicamente o IP da instância pelo servidor de metadados e criar um aplicativo Node.js para processar o tráfego de entrada diretamente na rede VPC.

Objetivos

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Cloud de Confiance by S3NS:

Antes de começar

  1. In the Cloud de Confiance console, on the project selector page, select or create a Cloud de Confiance 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

  2. Verify that billing is enabled for your Cloud de Confiance project.

  3. Ative as APIs Cloud DNS, Cloud Run, Compute Engine, Artifact Registry e Cloud Build, se alguma delas ainda não estiver ativada.

    Funções necessárias para ativar APIs

    Para ativar APIs, você precisa da permissão serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de Proprietário (roles/owner). Caso contrário, é possível receber essa permissão pelo papel de Administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.

    Ativar as APIs

  4. Instale e inicialize a CLI gcloud.
  5. Atualize os componentes:
    gcloud components update
  6. Defina o ID do projeto executando o seguinte comando:
    gcloud config set project PROJECT_ID
    Substitua PROJECT_ID pelo ID do seu projeto do Cloud de Confiance by S3NS .

Funções exigidas

Para receber as permissões necessárias para concluir o tutorial, peça para o administrador conceder a você os seguintes papéis do IAM no projeto:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias por meio de papéis personalizados ou de outros papéis predefinidos.

Criar uma conta de serviço personalizada

Crie uma conta de serviço personalizada com as permissões mínimas necessárias para registrar registros DNS. Para configurar a conta de serviço, faça o seguinte:

  1. Execute o seguinte comando para criar uma conta de serviço:

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

    Substitua SERVICE_ACCOUNT_NAME por um nome para sua conta de serviço personalizada, por exemplo, dns-worker-sa.

  2. Conceda o papel de administrador do Cloud DNS à conta de serviço:

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

Criar uma zona do Cloud DNS

Crie uma zona privada gerenciada do Cloud DNS chamada test-wp para registrar o IP da instância do pool de workers.

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

Criar um aplicativo Node.js

Crie um aplicativo Node.js que recupere o endereço IP da instância do pool de workers usando o servidor de metadados e o registre com o Cloud DNS.

  1. Crie uma pasta chamada worker e mude o diretório para ela:

    mkdir worker
    cd worker
    
  2. Crie um arquivo chamado setup_dns.sh e adicione o seguinte script, que é executado quando a instância do pool de workers é iniciada. Esse script usa o nome de host da instância para gerar o nome do registro DNS. Se houver mais de uma instância, várias instâncias poderão usar o mesmo nome de host, o que leva à criação de registros DNS sobrepostos.

    #!/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. Crie um arquivo server.js com o seguinte código para processar a entrada de endereço IP particular:

    // 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. Crie um script start.sh com o código a seguir para realizar a configuração de DNS primeiro, antes de executar o aplicativo 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. Crie o seguinte Dockerfile para empacotar o aplicativo em uma imagem:

    # 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 []
    

Implantar um pool de workers com entrada direta de VPC

Implante um pool de workers chamado test-cli-dns e anexe-o a uma rede VPC.

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

Substitua PROJECT_ID pelo ID do projeto do Cloud de Confiance by S3NS e SERVICE_ACCOUNT_NAME pelo nome da conta de serviço que você criou.

Testar o aplicativo

Os pools de workers do Cloud Run com entrada de VPC direta são projetados para tráfego somente interno. Elas não têm um IP público. Para verificar a funcionalidade de entrada, siga estas etapas para executar uma solicitação usando curl de uma VM do Compute Engine hospedada na mesma rede VPC e sub-rede:

  1. Crie uma VM de teste na mesma rede e região do seu pool de workers:

     gcloud compute instances create wp-test-vm \
         --zone=us-central1-a \
         --network=default \
         --subnet=default
    
  2. Conecte-se à VM de teste por SSH executando o seguinte comando:

     gcloud compute ssh wp-test-vm --zone=us-central1-a
    
  3. No terminal da VM, invoque o serviço no endereço IP particular da instância do pool de trabalhadores registrada no Cloud DNS:

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

    Você vai ver esta saída:

    Hello World!

Pronto. Você configurou com sucesso seu pool de workers do Cloud Run com entrada direta da VPC usando um endereço IP particular e o Cloud DNS.

Limpar

Para evitar cobranças extras na sua conta do Cloud de Confiance by S3NS , exclua todos os recursos implantados com este tutorial.

Excluir o projeto

Se você criou um novo projeto para este tutorial, exclua-o. Se você usou um projeto atual e precisa mantê-lo sem as mudanças adicionadas neste tutorial, exclua os recursos criados para o tutorial.

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  1. No console Cloud de Confiance , acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

Excluir recursos do tutorial

  1. Exclua o serviço do Cloud Run que você implantou neste tutorial. Os serviços do Cloud Run não geram custos até receberem solicitações.

    Para excluir o serviço do Cloud Run, execute o seguinte comando:

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME pelo nome do serviço;

    Também é possível excluir os serviços do Cloud Run no Cloud de Confiance console do.

  2. Remova a configuração de região padrão gcloud que você adicionou durante a configuração do tutorial:

     gcloud config unset run/region
    
  3. Remova a configuração do projeto:

     gcloud config unset project
    
  4. Exclua outros recursos do Cloud de Confiance by S3NS criados neste tutorial:

A seguir