Proxy explicite de l'interface PSC Vertex AI Pipelines

1. Introduction

Une interface Private Service Connect est une ressource qui permet à un réseau cloud privé virtuel (VPC) de producteur d'initier des connexions avec différentes destinations dans un réseau VPC consommateur. Les réseaux de producteurs et les réseaux de clients peuvent appartenir à différents projets et organisations.

Si un rattachement de réseau accepte une connexion depuis une interface Private Service Connect, Google Cloud attribue à l'interface une adresse IP d'un sous-réseau client spécifié par le rattachement de réseau. Les réseaux utilisateur et producteur sont connectés et peuvent communiquer à l'aide d'adresses IP internes.

Une connexion entre un rattachement de réseau et une interface Private Service Connect est semblable à la connexion entre un point de terminaison Private Service Connect et un rattachement de service, avec toutefois deux différences majeures :

  • Un rattachement de réseau permet à un réseau producteur d'établir des connexions avec un réseau consommateur (sortie de service géré), tandis qu'un point de terminaison permet à un réseau consommateur d'établir des connexions avec un réseau producteur (entrée de service géré).
  • Une connexion d'interface Private Service Connect est transitive. Cela signifie qu'un réseau de producteur peut communiquer avec d'autres réseaux connectés au réseau du client.

Considérations concernant l'accessibilité de l'interface PSC Vertex AI

  • L'interface PSC est capable de router le trafic vers des destinations VPC ou sur site dans le bloc d'adresses RFC1918.
  • L'interface PSC ciblant des blocs d'adresses non-RFC 1918 nécessite un proxy explicite déployé dans le VPC du consommateur avec une adresse RFC 1918. Dans le déploiement Vertex AI, le proxy doit être défini avec un nom de domaine complet du point de terminaison cible. Consultez la figure 1 qui représente le proxy explicite configuré dans les VPC des clients pour faciliter le routage vers les CIDR non rfc-1918 suivants :

[1] 240.0.0.0/4

[2] 203.0.113.0/2

[3]10.10.20.0/28 : aucun proxy requis, car cette plage appartient à la plage RFC1918.

  • Lorsque vous configurez votre déploiement avec une interface PSC uniquement, il conserve son accès Internet par défaut. Ce trafic sortant quitte directement le réseau locataire sécurisé et géré par Google.

476f87a96f153b95.png

Considérations concernant l'interface VPC-SC de Vertex AI PSC

  • Lorsque votre projet fait partie d'un périmètre VPC Service Controls, l'accès à Internet par défaut des locataires gérés par Google est bloqué par le périmètre pour empêcher l'exfiltration de données.
  • Pour autoriser l'accès au déploiement à l'Internet public dans ce scénario, vous devez configurer explicitement un chemin de sortie sécurisé qui achemine le trafic via votre VPC. La méthode recommandée pour y parvenir consiste à configurer un serveur proxy à l'intérieur de votre périmètre VPC avec une adresse RFC1918, puis à créer une passerelle Cloud NAT pour permettre à la VM proxy d'accéder à Internet.

Pour en savoir plus, consultez les ressources suivantes :

Configurer une interface Private Service Connect pour les ressources Vertex AI | Google Cloud

Ce que vous allez faire

Dans ce tutoriel, vous allez créer un déploiement complet de Vertex AI Pipelines avec une interface Private Service Connect (PSC) pour permettre la connectivité entre le producteur et le calcul du consommateur, comme illustré à la figure 1, en ciblant les points de terminaison non rfc-1928.

Figure 2

782ba8f1f3c3f522.png

Vous allez créer un seul attachement de réseau PSC dans le VPC consommateur en utilisant l'appairage DNS pour résoudre les VM des consommateurs dans le projet locataire hébergeant Vertex AI Training, ce qui permet les cas d'utilisation suivants :

  1. Déployez Vertex AI Pipelines et configurez une VM proxy pour qu'elle agisse en tant que proxy explicite, ce qui lui permet d'effectuer un wget sur une VM du sous-réseau de classe E.

Points abordés

  • Créer un rattachement de réseau
  • Comment un producteur peut utiliser un rattachement de réseau pour créer une interface PSC
  • Établir une communication du producteur au consommateur à l'aide de l'appairage DNS
  • Établir une communication avec un espace d'adresses IP non-RFC 1918 à partir de Vertex AI Pipelines

Prérequis

Projet Google Cloud

Autorisations IAM

2. Avant de commencer

Mettre à jour le projet pour qu'il soit compatible avec le tutoriel

Ce tutoriel utilise des $variables pour faciliter l'implémentation de la configuration gcloud dans Cloud Shell.

Dans Cloud Shell, procédez comme suit :

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid

Activation de l'API

Dans Cloud Shell, procédez comme suit :

gcloud services enable "compute.googleapis.com"
gcloud services enable "aiplatform.googleapis.com"
gcloud services enable "dns.googleapis.com"
gcloud services enable "notebooks.googleapis.com"
gcloud services enable "storage.googleapis.com"
gcloud services enable "cloudresourcemanager.googleapis.com"
gcloud services enable "artifactregistry.googleapis.com"
gcloud services enable "cloudbuild.googleapis.com"

3. Configuration du client

Créer le VPC consommateur

Dans Cloud Shell, procédez comme suit :

gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom

Créer les sous-réseaux consommateurs

Dans Cloud Shell, procédez comme suit :

gcloud compute networks subnets create class-e-subnet --project=$projectid --range=240.0.0.0/4 --network=consumer-vpc --region=us-central1

Dans Cloud Shell, procédez comme suit :

gcloud compute networks subnets create rfc1918-subnet1 --project=$projectid --range=10.10.10.0/28 --network=consumer-vpc --region=us-central1

Créer le sous-réseau de rattachement de réseau Private Service Connect

Dans Cloud Shell, procédez comme suit :

gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1

Configuration de Cloud Router et de NAT

Dans ce tutoriel, Cloud NAT est utilisé pour fournir un accès à Internet à la VM proxy, qui ne dispose pas d'adresse IP publique. Cloud NAT permet aux VM ne disposant que d'adresses IP privées de se connecter à Internet, ce qui leur permet d'effectuer des tâches telles que l'installation de packages logiciels.

Dans Cloud Shell, créez le routeur cloud.

gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1

Dans Cloud Shell, créez la passerelle NAT.

gcloud compute routers nats create cloud-nat-us-central1 --router=cloud-router-for-nat --auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges --region us-central1 --enable-logging --log-filter=ALL

4. Activer IAP

Pour permettre à IAP de se connecter à vos instances de VM, créez une règle de pare-feu qui :

  • S'applique à toutes les instances de VM auxquelles vous souhaitez être accessible à l'aide d'IAP.
  • Autorise le trafic entrant à partir de la plage d'adresses IP 35.235.240.0/20. Cette plage contient toutes les adresses IP qu'IAP utilise pour le transfert TCP.

Dans Cloud Shell, créez la règle de pare-feu IAP.

gcloud compute firewall-rules create ssh-iap-consumer \
    --network consumer-vpc \
    --allow tcp:22 \
    --source-ranges=35.235.240.0/20

5. Créer des instances de VM consommateur

Dans Cloud Shell, créez l'instance de VM consommateur, class-e-vm.

gcloud compute instances create class-e-vm \
    --project=$projectid \
    --machine-type=e2-micro \
    --image-family debian-11 \
    --no-address \
    --shielded-secure-boot \
    --image-project debian-cloud \
    --zone us-central1-a \
    --subnet=class-e-subnet \
    --metadata startup-script="#! /bin/bash
      sudo apt-get update
      sudo apt-get install tcpdump
      sudo apt-get install apache2 -y
      sudo service apache2 restart
      echo 'Class-e server !!' | tee /var/www/html/index.html
      EOF"

Dans Cloud Shell, créez l'instance de VM consommateur, proxy-vm, qui servira de proxy explicite pour Vertex AI Pipelines. Nous utiliserons tinyproxy comme application pour le trafic HTTP de proxy, bien que HTTPS soit également pris en charge.

gcloud compute instances create proxy-vm \
    --project=$projectid \
    --machine-type=e2-micro \
    --image-family debian-11 \
    --no-address \
    --can-ip-forward \
    --shielded-secure-boot \
    --image-project debian-cloud \
    --zone us-central1-a \
    --subnet=rfc1918-subnet1 \
    --metadata startup-script="#! /bin/bash
      sudo apt-get update
      sudo apt-get install tcpdump
      sudo apt-get install tinyproxy -y
      sudo apt-get install apache2 -y
      sudo service apache2 restart
      echo 'proxy server !!' | tee /var/www/html/index.html
      EOF"

6. Rattachement de réseau Private Service Connect

Les rattachements de réseau sont des ressources régionales qui représentent le côté utilisateur d'une interface Private Service Connect. Vous associez un seul sous-réseau à un rattachement de réseau, et le producteur attribue des adresses IP à l'interface Private Service Connect à partir de ce sous-réseau. Le sous-réseau doit se trouver dans la même région que le rattachement de réseau. Un rattachement réseau doit se trouver dans la même région que le service producteur.

Créer le rattachement de réseau

Dans Cloud Shell, créez le rattachement de réseau.

gcloud compute network-attachments create psc-network-attachment \
    --region=us-central1 \
    --connection-preference=ACCEPT_AUTOMATIC \
    --subnets=intf-subnet

Lister les rattachements de réseau

Dans Cloud Shell, listez le rattachement réseau.

gcloud compute network-attachments list

Décrire les rattachements de réseau

Dans Cloud Shell, décrivez le rattachement de réseau.

gcloud compute network-attachments describe psc-network-attachment --region=us-central1

Notez le nom psc-network-attachment, qui sera utilisé par le producteur lors de la création de l'interface Private Service Connect.

Pour afficher l'URL d'association au réseau PSC dans la console Cloud, accédez à :

Services réseau → Private Service Connect → Rattachement de réseau → psc-network-attachment

e191e54a103d2222.png

7. Zone DNS privée

Vous allez créer une zone Cloud DNS pour demo.com et la remplir avec des enregistrements A qui pointent vers les adresses IP de vos VM. L'appairage DNS sera ensuite déployé dans le job Vertex AI Pipelines, ce qui lui permettra d'accéder aux enregistrements DNS du consommateur.

Dans Cloud Shell, procédez comme suit :

gcloud dns --project=$projectid managed-zones create private-dns-codelab --description="" --dns-name="demo.com." --visibility="private" --networks="https://compute.googleapis.com/compute/v1/projects/$projectid/global/networks/consumer-vpc"

Dans Cloud Shell, exécutez une commande "describe" sur les instances de VM pour obtenir les adresses IP correspondantes.

gcloud compute instances describe class-e-vm --zone=us-central1-a | grep  networkIP:

gcloud compute instances describe proxy-vm --zone=us-central1-a | grep  networkIP:

Dans Cloud Shell, créez l'ensemble d'enregistrements pour la VM class-e-vm. Veillez à mettre à jour l'adresse IP en fonction de la sortie de votre environnement.

gcloud dns --project=$projectid record-sets create class-e-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="240.0.0.2"

Dans Cloud Shell, créez l'ensemble d'enregistrements pour la VM et la VM proxy. Veillez à mettre à jour l'adresse IP en fonction de la sortie de votre environnement.

gcloud dns --project=$projectid record-sets create proxy-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.2"

Créer une règle Cloud Firewall pour autoriser l'accès depuis l'interface PSC

Dans la section suivante, créez une règle de pare-feu qui autorise le trafic provenant de la pièce jointe de réseau PSC à accéder aux ressources de calcul RFC1918 dans le VPC du consommateur.

Dans Cloud Shell, créez la règle de pare-feu d'entrée qui autorise l'accès du sous-réseau de rattachement au réseau PSC à la VM proxy.

gcloud compute firewall-rules create allow-access-to-proxy \
    --network=consumer-vpc \
    --action=ALLOW \
    --rules=ALL \
    --direction=INGRESS \
    --priority=1000 \
    --source-ranges="192.168.10.0/28" \
    --destination-ranges="10.10.0.0/19" \
    --enable-logging

Dans Cloud Shell, créez la règle de pare-feu d'entrée qui autorise l'accès du sous-réseau proxy-vm au sous-réseau de classe E.

gcloud compute firewall-rules create allow-access-to-class-e \
    --network=consumer-vpc \
    --action=ALLOW \
    --rules=ALL \
    --direction=INGRESS \
    --priority=1000 \
    --source-ranges="10.10.10.0/28" \
    --destination-ranges="240.0.0.0/4" \
    --enable-logging

8. Mettre à jour le proxy explicite

Dans la section suivante, vous devrez vous connecter en SSH au proxy explicite, puis mettre à jour le fichier de configuration tinyproxy.conf et effectuer une réinitialisation.

Depuis Cloud Shell

gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid

Ouvrez le fichier de configuration tinyproxy et mettez-le à jour à l'aide de l'éditeur de votre choix. Vous trouverez ci-dessous un exemple utilisant VIM.

sudo vim /etc/tinyproxy/tinyproxy.conf

# Locate the "Listen" configuration line to restrict listening to only its private IP address of the Proxy-VM, rather than all interfaces. 

Listen 10.10.10.2

# Locate the "Allow" configuration line to allow requests ONLY from the PSC Network Attachment Subnet

Allow 192.168.10.0/24

Save the configs by the following steps:
1. Press the `ESC` key to enter Command Mode.
2. Type `:wq` to save (w) and quit (q).
3. Press `Enter`

Restart the tinyproxy service to apply the changes:
sudo systemctl restart tinyproxy

Validate the tinyproxy service is running:
sudo systemctl status tinyproxy

Perform an exit returning to cloud shell
exit

9. Créer un notebook Jupyter

La section suivante vous explique comment créer un notebook Jupyter. Ce notebook sera utilisé pour déployer un job Vertex AI Pipelines qui envoie une commande wget de Vertex AI Pipelines aux instances de test. Le chemin de données entre Vertex AI Pipelines et le réseau consommateur contenant les instances utilise une interface réseau Private Service Connect.

Créer un compte de service géré par l'utilisateur

Dans la section suivante, vous allez créer un compte de service qui sera associé à l'instance Vertex AI Workbench utilisée dans le tutoriel.

Dans le tutoriel, les rôles suivants seront appliqués au compte de service :

Dans Cloud Shell, créez le compte de service.

gcloud iam service-accounts create notebook-sa \
    --display-name="notebook-sa"

Dans Cloud Shell, mettez à jour le compte de service avec le rôle "Administrateur Storage".

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"

Dans Cloud Shell, mettez à jour le compte de service avec le rôle Utilisateur Vertex AI.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"

Dans Cloud Shell, mettez à jour le compte de service avec le rôle Administrateur Artifact Registry.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"

Dans Cloud Shell, attribuez le rôle "Éditeur Cloud Build" au compte de service.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/cloudbuild.builds.editor"

Dans Cloud Shell, autorisez le compte de service du notebook à utiliser le compte de service Compute Engine par défaut.

gcloud iam service-accounts add-iam-policy-binding \
    $(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')-compute@developer.gserviceaccount.com \
    --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" \
    --role="roles/iam.serviceAccountUser"

10. Créer une instance Vertex AI Workbench

Dans la section suivante, créez une instance Vertex AI Workbench qui intègre le compte de service notebook-sa créé précédemment.

Dans Cloud Shell, créez l'instance de client privé.

gcloud workbench instances create workbench-tutorial --vm-image-project=cloud-notebooks-managed --vm-image-family=workbench-instances --machine-type=n1-standard-4 --location=us-central1-a --subnet-region=us-central1 --subnet=rfc1918-subnet1 --disable-public-ip --shielded-secure-boot=true --shielded-integrity-monitoring=true --shielded-vtpm=true --service-account-email=notebook-sa@$projectid.iam.gserviceaccount.com

11. Mise à jour de l'agent de service Vertex AI

Vertex AI agit en votre nom pour effectuer des opérations telles que l'obtention d'une adresse IP à partir du sous-réseau de rattachement de réseau PSC utilisé pour créer l'interface PSC. Pour ce faire, Vertex AI utilise un agent de service (listé ci-dessous) qui nécessite l'autorisation Administrateur réseau.

service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com

Dans Cloud Shell, obtenez le numéro de votre projet.

gcloud projects describe $projectid | grep projectNumber

Dans Cloud Shell, obtenez le numéro de votre projet.

gcloud projects describe $projectid | grep projectNumber
projectNumber: '234086459238'

Dans Cloud Shell, définissez le numéro de votre projet.

projectnumber=YOUR-PROJECT-Number

Dans Cloud Shell, créez un compte de service pour AI Platform. Ignorez cette étape si vous disposez déjà d'un compte de service dans votre projet.

gcloud beta services identity create --service=aiplatform.googleapis.com --project=$projectnumber

Dans Cloud Shell, mettez à jour le compte de l'agent de service avec le rôle compute.networkAdmin.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/compute.networkAdmin"

Dans Cloud Shell, mettez à jour le compte de l'agent de service avec le rôle dns.peer.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/dns.peer"

Mise à jour du compte de service par défaut

Activez l'API Compute Engine et accordez à votre compte de service par défaut l'accès à Vertex AI. Notez que la propagation de la modification d'accès peut prendre un certain temps.

Dans Cloud Shell, mettez à jour le compte de service par défaut avec le rôle aiplatform.user.

gcloud projects add-iam-policy-binding $projectid \
  --member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
    --role="roles/aiplatform.user"

Dans Cloud Shell, mettez à jour le compte de service par défaut avec le rôle storage.admin.

gcloud projects add-iam-policy-binding $projectid \
  --member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
    --role="roles/storage.admin"

Dans Cloud Shell, mettez à jour le compte de service par défaut avec le rôle storage.admin.

gcloud projects add-iam-policy-binding $projectid \
  --member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
    --role="roles/artifactregistry.admin"

12. Activer Tcpdump

Pour valider la connectivité IP depuis Vertex AI Pipelines, nous pouvons utiliser TCPDUMP. Cela nous permettra d'observer la communication provenant du sous-réseau de rattachement au réseau PSC, 192.168.10.0/28, lors de l'appel de la requête GET de Vertex AI Pipelines à la VM, class-e-vm.demo.com (240.0.0.0/4).

Depuis Cloud Shell, connectez-vous en SSH à la VM de proxy.

gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid

À partir de l'OS de la VM proxy, exécutez le filtrage tcpdump sur le sous-réseau de rattachement réseau class-e-vm et PSC.

sudo tcpdump -i any net 240.0.0.0/4 or 192.168.10.0/28 -nn

Ouvrez un nouvel onglet Cloud Shell, mettez à jour la variable de votre projet et connectez-vous via SSH à la VM class-e-vm.

gcloud compute ssh --zone us-central1-a "class-e-vm" --tunnel-through-iap --project $projectid

À partir de l'OS de la VM class-e-vm, exécutez le filtrage tcpdump sur le sous-réseau proxy-vm.

sudo tcpdump -i any net 10.10.10.0/28 -nn

13. Déployer un job Vertex AI Pipelines

Dans la section suivante, vous allez créer un notebook pour effectuer un wget réussi de Vertex AI Pipelines vers le proxy explicite. Cela vous permet d'accéder aux VM non-RFC 1918, telles que class-e-vm. Un proxy explicite n'est pas nécessaire pour que Vertex AI Pipelines accède à rfc1918-vm, car sa cible est une adresse IP RFC 1918.

Exécutez le job d'entraînement dans l'instance Vertex AI Workbench.

  1. Dans la console Google Cloud, accédez à l'onglet "Instances" de la page Vertex AI Workbench.
  2. À côté du nom de votre instance Vertex AI Workbench (workbench-tutorial), cliquez sur "Ouvrir JupyterLab". Votre instance Vertex AI Workbench ouvre JupyterLab.
  3. Sélectionnez Fichier > Nouveau > Notebook.
  4. Sélectionnez Kernel > Python 3.

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

# Install gcloud
!pip install google-cloud

# Install the pipeline required packages
!pip install --upgrade google-cloud-aiplatform \
                         google-cloud-storage \
                         kfp \
                         google-cloud-pipeline-components

# Import libraries
from time import gmtime, strftime
import json
import requests

Dans votre notebook JupyterLab, créez une cellule, puis mettez à jour et exécutez le code suivant. Veillez à remplacer PROJECT_ID par les informations de votre environnement.

import json
import requests
import pprint

PROJECT_ID = 'YOUR-PROJECT-ID' #Enter your project ID
PROJECT_NUMBER=!gcloud projects list --filter="project_id:$PROJECT_ID" --format="value(PROJECT_NUMBER)"
PROJECT_NUMBER=str(PROJECT_NUMBER).strip('[').strip(']').strip("'")
print(PROJECT_NUMBER)

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

# us-central1 is used for the codelab
REGION = "us-central1" #@param {type:"string"}
SERVICE_NAME = "aiplatform" #@param {type:"string"}
SERVICE ="{}.googleapis.com".format(SERVICE_NAME)
ENDPOINT="{}-{}.googleapis.com".format(REGION, SERVICE_NAME)
API_VERSION = "v1" # @param {type: "string"}

LOCATION = REGION

Dans votre notebook JupyterLab, créez une cellule et exécutez la configuration ci-dessous. Notez les points suivants :

  • proxy_server = "http://proxy-vm.demo.com:8888" Le nom de domaine complet est associé à la VM de proxy déployée dans le VPC consommateur. Nous utilisons le peering DNS pour résoudre le nom de domaine complet lors d'une étape ultérieure.
%%writefile main.py

import logging
import socket
import sys
import os

def make_api_request(url: str, proxy_vm_ip: str, proxy_vm_port: str):
    """
    Makes a GET request to a non-rfc1918 API and saves the response.

    Args:
        url: The URL of the API to send the request to.
    """
    import requests

    try:
        # response = requests.get(url)
        proxy_server = f"http://proxy-vm.demo.com:8888" # replace with you VM's IP and proxy port.

        proxies = {
          "http": proxy_server,
          "https": proxy_server,
        }

        response = requests.get(url, proxies=proxies)
        logging.info(response.text)

        response.raise_for_status()  # Raise an exception for bad status codes
        logging.info(f"Successfully fetched data from {url}")
    except requests.exceptions.RequestException as e:
        logging.error(f"An error occurred: {e}")
        raise e

if __name__ == '__main__':
  # Configure logging to print clearly to the console
  logging.basicConfig(
      level=logging.INFO,
      format='%(levelname)s: %(message)s',
      stream=sys.stdout
  )
  url_to_test = os.environ['NONRFC_URL']
  proxy_vm_ip = os.environ['PROXY_VM_IP']
  proxy_vm_port = os.environ['PROXY_VM_PORT']

  logging.info(f"url_to_test: {url_to_test}")
  logging.info(f"proxy_vm_ip: {proxy_vm_ip}")
  logging.info(f"proxy_vm_port: {proxy_vm_port}")
  make_api_request(url_to_test, proxy_vm_ip, proxy_vm_port)

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

%%writefile Dockerfile
FROM python:3.9-slim

RUN apt-get update && \
  apt-get install -y iputils-ping && \
  apt-get install -y wget

RUN pip install cloudml-hypertune requests kfp

COPY main.py /main.py

ENTRYPOINT ["python3", "/main.py"]

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

!gcloud artifacts repositories create pipelines-test-repo-psc --repository-format=docker --location=us-central1

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

IMAGE_PROJECT = PROJECT_ID
IMAGE_REPO = 'pipelines-test-repo-psc' 
IMAGE_NAME = 'nonrfc-ip-call'
TAG = 'v1'

IMAGE_URI= f'us-central1-docker.pkg.dev/{IMAGE_PROJECT}/{IMAGE_REPO}/{IMAGE_NAME}:{TAG}'
IMAGE_URI

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

!gcloud auth configure-docker us-docker.pkg.dev --quiet

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante. Ignorez l'erreur (gcloud.builds.submit) si elle s'affiche.

!gcloud builds submit --tag {IMAGE_URI} --region=us-central1

Dans votre notebook JupyterLab, créez et exécutez la cellule ci-dessous. Notez les points suivants :

  • L'appairage DNS aux VPC consommateurs est configuré à l'aide de dnsPeeringConfigs (dnsPeeringConfigs) pour le nom de domaine demo.com.
  • Le proxy explicite, défini comme la variable PROXY_VM_IP, est proxy-vm.demo.com. La résolution est gérée via l'appairage DNS dans le VPC du consommateur.
  • Le port 8888 est le port d'écoute (par défaut) configuré dans tinyproxy.
  • La résolution de wget vers class-e-vm-demo.com s'effectue via l'appairage DNS.
  • Le code spécifie le "psc-network-attachment" pour Vertex, ce qui lui permet d'utiliser le sous-réseau de rattachement de réseau pour déployer deux instances d'interface PSC.
import json
from datetime import datetime


JOB_ID_PREFIX='test_psci-nonRFC' #@param {type:"string"}
JOB_ID = '{}_{}'.format(JOB_ID_PREFIX, datetime.now().strftime("%Y%m%d%H%M%S"))

# PSC-I configs

PRODUCER_PROJECT_ID = PROJECT_ID
DNS_DOMAIN = 'class-e-vm.demo.com' #@param {type:"string"}
NON_RFC_URL = f"http://{DNS_DOMAIN}"

PROXY_VM_IP = "proxy-vm.demo.com" #@param {type:"string"}
PROXY_VM_PORT = "8888" #@param {type:"string"}

CUSTOM_JOB = {
  "display_name": JOB_ID,
  "job_spec": {
      "worker_pool_specs": [
          {
           "machine_spec": {
             "machine_type": "n1-standard-4",
           },
           "replica_count": 1,
           "container_spec": {
             "image_uri": IMAGE_URI,
             "env": [{
               "name": "NONRFC_URL",
               "value": NON_RFC_URL
             },
             {
               "name": "PROXY_VM_IP",
               "value": PROXY_VM_IP
             },
             {
               "name": "PROXY_VM_PORT",
               "value": PROXY_VM_PORT
             }]
           },
         },
      ],
      "enable_web_access": True,
      "psc_interface_config": {
        "network_attachment": "psc-network-attachment",
        "dns_peering_configs": [
          {
            "domain": "demo.com.",
            "target_project": PROJECT_ID,
            "target_network": "consumer-vpc"
          },
        ]
      },
  }
}

print(json.dumps(CUSTOM_JOB, indent=2))

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

import requests
bearer_token = !gcloud auth application-default print-access-token
headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer {}'.format(bearer_token[0]),
}

request_uri = f"https://{REGION}-aiplatform.googleapis.com/{API_VERSION}/projects/{PROJECT_NUMBER}/locations/{REGION}/customJobs/"

print("request_uri: ", request_uri)

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

response_autopush = requests.post(request_uri, json=CUSTOM_JOB, headers=headers)
response = response_autopush
print("response:", response)
if response.reason == 'OK':
  job_name = response.json()['name']
  job_id = job_name.split('/')[-1]
  print("Created Job: ", response.json()['name'])
else:
  print(response.text)

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

# Print KFP SDK version (should be >= 1.6)
! python3 -c "import kfp; print('KFP SDK version: {}'.format(kfp.__version__))"

# Print AI Platform version
! python3 -c "from google.cloud import aiplatform; print('AI Platform version: {}'.format(aiplatform.__version__))"

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

BUCKET_URI = "your-unique-bucket" # Provide a globally unique bucket name

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

!gcloud storage buckets create gs://{BUCKET_URI}

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

# pipeline parameters
CACHE_PIPELINE = False # @param {type: "string"}
_DEFAULT_IMAGE = IMAGE_URI
BUCKET_URI = "gs://{BUCKET_URI}"  # @param {type: "string"}
PIPELINE_ROOT = f"{BUCKET_URI}/pipeline_root/intro"
PIPELINE_DISPLAY_NAME = "pipeline_nonRFCIP" # @param {type: "string"}

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

from re import S
import kfp
from kfp import dsl
from kfp.dsl import container_component, ContainerSpec
from kfp import compiler
from google.cloud import aiplatform


# ==== Component with env variable ====

@container_component
def dns_peering_test_op(dns_domain: str, proxy_vm_ip:str, proxy_vm_port:str):
    return ContainerSpec(
        image=_DEFAULT_IMAGE,
        command=["bash", "-c"],
        args=[
            """
            apt-get update && apt-get install inetutils-traceroute inetutils-ping netcat-openbsd curl -y

            echo "Local IP(s): $(hostname -I)"

            echo "Attempting to trace route to %s"
            traceroute -w 1 -m 7 "%s"

            echo "Sending curl requests to http://%s via proxy %s:%s and recording trace..."
            if curl -L -v --trace-ascii /dev/stdout -x http://%s:%s "http://%s"; then
                echo "Curl request succeeded!"
            else
                echo "Curl request failed!"
                exit 1
            fi
            """ % (dns_domain, dns_domain, dns_domain, proxy_vm_ip, proxy_vm_port, proxy_vm_ip, proxy_vm_port, dns_domain)

        ]
    )

# ==== Pipeline ====
@dsl.pipeline(
    name="dns-peering-test-pipeline",
    description="Test DNS Peering using env variable",
    pipeline_root=PIPELINE_ROOT,
)
def dns_peering_test_pipeline(dns_domain: str, proxy_vm_ip:str, proxy_vm_port:str):
    dns_test_task = dns_peering_test_op(dns_domain=dns_domain, proxy_vm_ip=proxy_vm_ip, proxy_vm_port=proxy_vm_port)
    dns_test_task.set_caching_options(enable_caching=CACHE_PIPELINE)

# ==== Compile pipeline ====
if __name__ == "__main__":
    aiplatform.init(project=PROJECT_ID, location=LOCATION)

    compiler.Compiler().compile(
        pipeline_func=dns_peering_test_pipeline,
        package_path="dns_peering_test_pipeline.yaml",
    )
    print("✅ Pipeline compiled to dns_peering_test_pipeline.yaml")

Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.

# Define the PipelineJob body; see API Reference https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.pipelineJobs/create

import requests, json
import datetime

bearer_token = !gcloud auth application-default print-access-token
headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer {}'.format(bearer_token[0]),
}

request_uri = f"https://{REGION}-aiplatform.googleapis.com/{API_VERSION}/projects/{PROJECT_NUMBER}/locations/{REGION}/pipelineJobs/"

print("request_uri: ", request_uri)

14. Validation de l'interface PSC

Vous pouvez également afficher les adresses IP de l'association de réseau utilisées par Vertex AI Pipelines en accédant à :

Services réseau → Private Service Connect → Rattachement de réseau → psc-network-attachment

Sélectionnez le projet locataire (nom de projet se terminant par "-tp").

f47150235fedb8ce.png

Le champ en surbrillance indique l'adresse IP utilisée par Vertex AI Pipelines à partir du rattachement de réseau PSC.

39e7b251aeb4f191.png

15. Validation de Cloud Logging

La première exécution du job Vertex AI Pipelines prendra environ 14 minutes. Les exécutions suivantes seront beaucoup plus courtes. Pour valider la réussite de l'opération, procédez comme suit :

Accédez à Vertex AI > Entraînement > Tâches personnalisées.

Sélectionnez le job personnalisé exécuté.

a9be0395c842aa6f.png

Sélectionnez "Afficher les journaux".

53e30765ba5827f3.png

Une fois Cloud Logging disponible, sélectionnez "Exécuter la requête" qui génère la sélection en surbrillance ci-dessous, confirmant que wget a réussi à passer de Vertex AI Pipelines à la VM de classe E.

f2c5d9fdf5cc8bed.png

3b3788603bb433ee.png

16. Validation de TCPDump

Examinons le résultat TCPDUMP qui valide davantage la connectivité aux instances de calcul :

À partir de la VM de proxy, observez la requête HTTP GET et la réponse 200 OK.

03:05:34.778574 ens4  Out IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 1:63, ack 1, win 511, options [nop,nop,TS val 1435446009 ecr 2475360885], length 62: HTTP: GET / HTTP/1.0
03:05:34.778946 ens4  In  IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 63, win 506, options [nop,nop,TS val 2475360889 ecr 1435446009], length 0
03:05:34.778974 ens4  Out IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 63:185, ack 1, win 511, options [nop,nop,TS val 1435446010 ecr 2475360889], length 122: HTTP
03:05:34.781999 ens4  In  IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 185, win 506, options [nop,nop,TS val 2475360892 ecr 1435446010], length 0
03:05:34.906678 ens4  In  IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [P.], seq 1:265, ack 185, win 506, options [nop,nop,TS val 2475361016 ecr 1435446010], length 264: HTTP: HTTP/1.1 200 OK

À partir de class-e-vm, observez la requête HTTP GET et la réponse 200 OK.

03:05:34.778768 ens4  In  IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 1:63, ack 1, win 511, options [nop,nop,TS val 1435446009 ecr 2475360885], length 62: HTTP: GET / HTTP/1.0
03:05:34.778819 ens4  Out IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 63, win 506, options [nop,nop,TS val 2475360889 ecr 1435446009], length 0
03:05:34.781815 ens4  In  IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 63:185, ack 1, win 511, options [nop,nop,TS val 1435446010 ecr 2475360889], length 122: HTTP
03:05:34.781856 ens4  Out IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 185, win 506, options [nop,nop,TS val 2475360892 ecr 1435446010], length 0
03:05:34.906503 ens4  Out IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [P.], seq 1:265, ack 185, win 506, options [nop,nop,TS val 2475361016 ecr 1435446010], length 264: HTTP: HTTP/1.1 200 OK

17. Effectuer un nettoyage

Dans Cloud Shell, supprimez les composants du tutoriel.

gcloud compute instances delete proxy-vm --zone=us-central1-a --quiet

gcloud compute instances delete workbench-tutorial --zone=us-central1-a --quiet

gcloud compute routers delete cloud-router-for-nat --region=us-central1 --quiet

gcloud compute network-attachments delete psc-network-attachment --region=us-central1 --quiet

gcloud compute networks subnets delete intf-subnet rfc1918-subnet1 --region=us-central1 --quiet

gcloud dns record-sets delete class-e-vm.demo.com --zone=private-dns-codelab  --type=A
gcloud dns record-sets delete proxy-vm.demo.com --zone=private-dns-codelab  --type=A

gcloud dns managed-zones delete private-dns-codelab
gcloud compute networks delete consumer-vpc --quiet

18. Félicitations

Félicitations ! Vous avez configuré et validé une interface Private Service Connect avec Vertex AI Pipelines.

Vous avez créé l'infrastructure consommateur et ajouté un rattachement de réseau qui a permis au producteur de créer une VM multi-NIC pour faire le pont entre les communications consommateur et producteur. Vous avez appris à créer un appairage DNS lors du déploiement d'un proxy explicite dans le réseau VPC consommateur, ce qui a permis la connectivité à l'instance class-e-vm qui n'est pas routable directement depuis Vertex.

Cosmopup pense que les tutoriels sont géniaux !!

c911c127bffdee57.jpeg

Et ensuite ?

Lectures et vidéos complémentaires

Documents de référence