Enregistrer des adresses IP privées pour les pools de nœuds de calcul à l'aide de Cloud DNS

Ce tutoriel explique comment enregistrer l'adresse IP privée d'une instance de pool de nœuds de calcul Cloud Run dans une zone gérée Cloud DNS. Dans ce tutoriel, vous utilisez un script de démarrage pour détecter dynamiquement l'adresse IP de l'instance via le serveur de métadonnées, et vous créez une application Node.js pour gérer l'entrée directement dans votre réseau VPC.

Objectifs

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud:

Obtenez une estimation des coûts en fonction de votre utilisation prévue, utilisez le simulateur de coût.

Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai sans frais.

Avant de commencer

  1. Connectez-vous à votre Google Cloud compte. Si vous n'avez jamais utilisé Google Cloud, créez un compte pour évaluer les performances de nos produits dans des scénarios réels. Les nouveaux clients bénéficient également de 300 $de crédits sans frais pour exécuter, tester et déployer des charges de travail.
  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. Activez les API Cloud DNS, Cloud Run, Compute Engine, Artifact Registry et Cloud Build.

    Rôles requis pour activer les API

    Pour activer les API, vous avez besoin du rôle IAM Administrateur d'utilisation du service (roles/serviceusage.serviceUsageAdmin), qui contient l'autorisation serviceusage.services.enable. Découvrez comment attribuer des rôles.

    Activer les API

  7. Installez et initialisez gcloud CLI.
  8. Mettez à jour les composants :
    gcloud components update
  9. Définissez l'ID de votre projet en exécutant la commande suivante :
    gcloud config set project PROJECT_ID
    Remplacez PROJECT_ID par l'ID de votre Google Cloud projet.

Rôles requis

Pour obtenir les autorisations nécessaires pour suivre le tutoriel, demandez à votre administrateur de vous attribuer les rôles IAM suivants sur votre projet :

Pour en savoir plus sur l'attribution de rôles, consultez la page Gérer l'accès aux projets, aux dossiers et aux organisations.

Vous pouvez également obtenir les autorisations requises via des rôles personnalisés ou d'autres rôles prédéfinis.

Créer un compte de service personnalisé

Créez un compte de service personnalisé avec les autorisations minimales requises pour enregistrer les enregistrements DNS. Pour configurer le compte de service, procédez comme suit :

  1. Créez un compte de service en exécutant la commande suivante :

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

    Remplacez SERVICE_ACCOUNT_NAME par le nom de votre compte de service personnalisé, par exemple dns-worker-sa.

  2. Accordez le rôle Administrateur Cloud DNS au compte de service :

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

Créer une zone Cloud DNS

Créez une zone gérée Cloud DNS privée nommée test-wp pour enregistrer l'adresse IP de l'instance de votre pool de nœuds de calcul.

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

Créer une application Node.js

Créez une application Node.js qui récupère l'adresse IP de l'instance du pool de nœuds de calcul à l'aide du serveur de métadonnées, puis l'enregistre auprès de Cloud DNS.

  1. Créez un dossier nommé worker et accédez-y :

    mkdir worker
    cd worker
    
  2. Créez un fichier nommé setup_dns.sh et ajoutez le script suivant, qui s'exécute au démarrage de l'instance de votre pool de nœuds de calcul. Ce script utilise le nom d'hôte de l'instance pour générer le nom de l'enregistrement DNS. S'il existe plusieurs instances, elles peuvent utiliser le même nom d'hôte, ce qui entraîne la création d'enregistrements DNS qui se chevauchent.

    #!/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. Créez un fichier server.js avec le code suivant pour gérer l'entrée d'adresse IP privée :

    // 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. Créez un script start.sh avec le code suivant pour effectuer d'abord la configuration DNS, avant d'exécuter votre application 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. Créez le Dockerfile suivant pour empaqueter l'application dans une image :

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

Déployer un pool de nœuds de calcul avec une entrée VPC directe

Déployez un pool de nœuds de calcul nommé test-cli-dns et associez-le à un réseau 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

Remplacez PROJECT_ID par l'ID de votre Google Cloud projet et SERVICE_ACCOUNT_NAME par le nom du compte de service que vous avez créé.

Tester votre application

Les pools de nœuds de calcul Cloud Run avec une entrée VPC directe sont conçus pour le trafic interne uniquement. Ils ne disposent pas d'adresse IP publique. Pour vérifier la fonctionnalité d'entrée, procédez comme suit pour exécuter une requête à l'aide de curl à partir d'une VM Compute Engine hébergée sur le même réseau VPC et le même sous-réseau :

  1. Créez une VM de test dans le même réseau et la même région que votre pool de nœuds de calcul :

     gcloud compute instances create wp-test-vm \
         --zone=us-central1-a \
         --network=default \
         --subnet=default
    
  2. Connectez-vous à la VM de test via SSH en exécutant la commande suivante :

     gcloud compute ssh wp-test-vm --zone=us-central1-a
    
  3. À partir du terminal de la VM, appelez votre service à l'adresse IP privée de l'instance du pool de nœuds de calcul enregistrée auprès de Cloud DNS :

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

    Le résultat suivant s'affiche :

    Hello World!

Opération réussie ! Vous avez configuré votre pool de nœuds de calcul Cloud Run avec une entrée VPC directe à l'aide d'une adresse IP privée et de Cloud DNS.

Effectuer un nettoyage

Pour éviter que des frais supplémentaires ne soient facturés sur votre Google Cloud compte, supprimez toutes les ressources que vous avez déployées avec ce tutoriel.

Supprimer le projet

Si vous avez créé un projet pour ce tutoriel, supprimez-le. Si vous avez utilisé un projet existant et que vous devez le conserver sans les modifications que vous avez ajoutées dans ce tutoriel, supprimez les ressources que vous avez créées pour le tutoriel.

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour supprimer le projet :

  1. Dans la Google Cloud console, accédez à la page Gérer les ressources.

    Accéder à la page "Gérer les ressources"

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez Arrêter pour supprimer le projet.

Supprimer les ressources du tutoriel

  1. Supprimez le service Cloud Run que vous avez déployé dans ce tutoriel. Les services Cloud Run n'entraînent pas de coûts tant qu'ils ne reçoivent pas de requêtes.

    Pour supprimer votre service Cloud Run, exécutez la commande suivante :

    gcloud run services delete SERVICE-NAME

    Remplacez SERVICE-NAME par le nom de votre service.

    Vous pouvez également supprimer des services Cloud Run à partir de la Google Cloud console.

  2. Supprimez la configuration de région par défaut gcloud que vous avez ajoutée lors de la configuration du tutoriel :

     gcloud config unset run/region
    
  3. Supprimez la configuration du projet :

     gcloud config unset project
    
  4. Supprimez les autres Google Cloud ressources créées dans ce tutoriel :

Étape suivante