Vertex AI Pipelines PSC Interface SWP

1. Introduzione

Un'interfaccia Private Service Connect è una risorsa che consente a una rete Virtual Private Cloud (VPC) producer di avviare connessioni a varie destinazioni in una rete VPC consumer. Le reti producer e consumer possono trovarsi in progetti e organizzazioni diversi.

Se un collegamento di rete accetta una connessione da un'interfaccia Private Service Connect, Google Cloud assegna all'interfaccia un indirizzo IP da una subnet consumer specificata dal collegamento di rete. Le reti consumer e producer sono connesse e possono comunicare utilizzando indirizzi IP interni.

Una connessione tra un collegamento di rete e un'interfaccia Private Service Connect è simile alla connessione tra un endpoint Private Service Connect e un collegamento al servizio, ma presenta due differenze fondamentali:

  • Un collegamento di rete consente a una rete producer di avviare connessioni a una rete consumer (uscita del servizio gestito), mentre un endpoint consente a una rete consumer di avviare connessioni a una rete producer (ingresso del servizio gestito).
  • Una connessione di interfaccia Private Service Connect è transitiva. Ciò significa che una rete producer può comunicare con altre reti connesse alla rete consumer.

d7dc28d6567e6283.pngFigura 1

Considerazioni sull'accessibilità dell'interfaccia PSC di Vertex AI

  • L'interfaccia PSC di Vertex AI è in grado di instradare il traffico verso destinazioni in un VPC o on-premise all'interno del blocco di indirizzi RFC1918.
  • Il targeting dell'interfaccia PSC di blocchi di indirizzi non RFC-1918 richiede un proxy esplicito di cui è stato eseguito il deployment nel VPC del consumer con un indirizzo RFC-1918. All'interno del deployment di Vertex AI, il proxy deve essere definito insieme a un FQDN dell'endpoint di destinazione. Vedi la figura 1 che rappresenta la modalità proxy esplicita Secure Web Proxy (SWP) configurata nel VPC consumer per facilitare il routing ai seguenti CIDR non RFC-1918:
  1. 240.0.0.0/4
  2. 203.0.113.0/24
  3. 10.10.20.0/28 non richiede proxy e rientra nell'intervallo RFC-1918.
  4. In uscita da internet

Connessione a internet per la rete tenant gestita da Google:

Interfaccia PSC di Vertex AI senza VPC-SC

  • Quando configuri il deployment con una sola interfaccia PSC, questa mantiene l'accesso a internet predefinito. Questo traffico in uscita esce direttamente dalla rete tenant gestita da Google.

Interfaccia PSC di Vertex AI con VPC-SC

  • Quando il tuo progetto fa parte di un perimetro dei Controlli di servizio VPC, l'accesso a internet predefinito del tenant gestito da Google viene bloccato dal perimetro per impedire l'esfiltrazione di dati.
  • Per consentire l'accesso al deployment alla rete internet pubblica in questo scenario, devi configurare esplicitamente un percorso di uscita sicuro che indirizzi il traffico attraverso il VPC connesso a Vertex AI. Il deployment di un server proxy all'interno della rete VPC con indirizzo RFC 1918, abbinato a un gateway Cloud NAT, è un modo per raggiungere questo obiettivo. Tieni presente che puoi utilizzare anche Secure Web Proxy per inoltrare il traffico a internet. La creazione di Secure Web Proxy crea automaticamente un gateway Cloud NAT.

Per ulteriori informazioni, consulta le seguenti risorse:

Configura un'interfaccia Private Service Connect per le risorse Vertex AI | Google Cloud

Cosa creerai

In questo tutorial, creerai un deployment completo di Vertex AI Pipelines con l'interfaccia Private Service Connect (PSC) per consentire la connettività dal producer al calcolo del consumer, come illustrato nella Figura 1, che ha come target l'endpoint non RFC 1918 in class-e-subnet.

2d095dc2f4de6b4b.pngFigura 2

Creerai un singolo psc-network-attachment nel VPC consumer sfruttando il peering DNS per risolvere le VM consumer nel progetto tenant che ospita Vertex AI Training, ottenendo i seguenti casi d'uso:

Esegui il deployment di Vertex AI Pipelines e configura Secure Web Proxy in modalità proxy esplicito, consentendogli di eseguire un wget su una VM nella subnet di classe E.

Cosa imparerai a fare

  • Come creare un collegamento di rete
  • Come un producer può utilizzare un collegamento di rete per creare un'interfaccia PSC
  • Come stabilire il peering DNS per risolvere i domini privati configurati nella rete VPC consumer dalle reti VPC gestite da Google
  • Come inoltrare il traffico dall'interfaccia PSC di Vertex AI a Secure Web Proxy
  • Come stabilire la comunicazione con lo spazio di indirizzi IP non RFC-1918 da Vertex AI Pipelines

Che cosa ti serve

Progetto Google Cloud

Autorizzazioni IAM

2. Prima di iniziare

Aggiornare il progetto per supportare il tutorial

Questo tutorial utilizza le variabili $per facilitare l'implementazione della configurazione di gcloud in Cloud Shell.

In Cloud Shell, esegui le seguenti operazioni:

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

Abilitazione delle API

In Cloud Shell, esegui le seguenti operazioni:

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"
gcloud services enable "networkservices.googleapis.com"
gcloud services enable "networksecurity.googleapis.com"
gcloud services enable "certificatemanager.googleapis.com"

3. Configurazione consumatore

Crea il VPC consumer

In Cloud Shell, esegui le seguenti operazioni:

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

Crea le subnet consumer

In Cloud Shell, esegui le seguenti operazioni:

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

In Cloud Shell, esegui le seguenti operazioni:

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

Crea la subnet solo proxy

gcloud compute networks subnets create proxy-only-uscentral1 \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=us-central1 \
    --network=consumer-vpc \
    --range=10.10.100.0/26

Crea la subnet del collegamento di rete Private Service Connect

In Cloud Shell, esegui le seguenti operazioni:

gcloud compute networks subnets create intf-subnet \
--project=$projectid \
--range=192.168.10.0/28 \
--network=consumer-vpc \
--region=us-central1 \
--enable-private-ip-google-access

Configurazione di router Cloud e NAT

Google Cloud Secure Web Proxy esegue automaticamente il provisioning e la gestione di un gateway Cloud NAT e di un router Cloud associato nella regione in cui viene implementato.

4. Abilitare IAP

Per consentire a IAP (Identity-Aware Proxy) di connettersi alle tue istanze VM, crea una regola firewall che:

  • Si applichi a tutte le istanze VM a cui vuoi accedere tramite IAP.
  • Consente il traffico in entrata dall'intervallo IP 35.235.240.0/20. Questo intervallo contiene tutti gli indirizzi IP che utilizzati da IAP per l'inoltro TCP.

In Cloud Shell, crea la regola firewall IAP.

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

5. Crea istanze VM consumer

In Cloud Shell, crea l'istanza VM consumer, 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 \ 
    --private-network-ip=240.0.0.2

6. Secure Web Proxy

La modalità esplicita (o modalità di routing proxy esplicito) di Secure Web Proxy è un metodo di deployment in cui i carichi di lavoro client devono essere configurati in modo esplicito per utilizzare l'indirizzo IP interno o il nome di dominio completo e la porta di SWP come proxy di inoltro.

Nei passaggi riportati di seguito, assicurati di modificare YOUR-PROJECT-ID con il tuo ID progetto.

Crea un proxy web:

In Cloud Shell, crea il file policy.yaml utilizzando un editor di testo:

cat > policy.yaml << EOF
description: basic Secure Web Proxy policy
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1
EOF

In Cloud Shell, genera la policy Secure Web Proxy:

gcloud network-security gateway-security-policies import policy1 \
    --source=policy.yaml \
    --location=us-central1

Nella sezione seguente, crea una regola per consentire l'accesso a class-e-vm in base all'host sessionMatcher.

In Cloud Shell, crea il file rule1.yaml utilizzando un editor di testo:

cat > rule1.yaml << EOF
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1/rules/allow-nonrfc-classe
description: Allow nonrfc class-e
enabled: true
priority: 1
basicProfile: ALLOW
sessionMatcher: host() == 'class-e-vm.demo.com'
EOF

Nella sezione seguente, crea una regola per consentire l'accesso al notebook Jupyter per consentire l'installazione di apache2 sulla VM "class-e".

In Cloud Shell, crea il file rule2.yaml utilizzando un editor di testo:

cat > rule2.yaml << EOF
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1/rules/allow-apache2
description: Allow Apache2 install on class-e VM
enabled: true
priority: 2
basicProfile: ALLOW
sessionMatcher: inIpRange(source.ip,'240.0.0.2')
EOF

In Cloud Shell, genera la regola della policy di sicurezza 1:

gcloud network-security gateway-security-policies rules import allow-nonrfc-classe \
    --source=rule1.yaml \
    --location=us-central1 \
    --gateway-security-policy=policy1

In Cloud Shell, genera la regola della policy di sicurezza 2:

gcloud network-security gateway-security-policies rules import allow-apache2 \
    --source=rule2.yaml \
    --location=us-central1 \
    --gateway-security-policy=policy1

Per supportare Vertex AI Training, configura il gateway Secure Web Proxy con queste impostazioni:

  • Porta di ascolto: utilizza la stessa porta configurata nelle impostazioni del proxy esplicite del codice dell'applicazione Vertex AI (ad es. 8080).
  • Indirizzo: assegna un indirizzo IP privato dall'intervallo RFC 1918.
  • Modalità di routing: imposta questo valore su EXPLICIT_ROUTING_MODE

In Cloud Shell, crea un file gateway.yaml per definire il gateway Secure Web Proxy:

cat > gateway.yaml << EOF
name: projects/$projectid/locations/us-central1/gateways/swp1
type: SECURE_WEB_GATEWAY
addresses: ["10.10.10.5"]
ports: [8080]
gatewaySecurityPolicy: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1
network: projects/$projectid/global/networks/consumer-vpc
subnetwork: projects/$projectid/regions/us-central1/subnetworks/rfc1918-subnet1
routingMode: EXPLICIT_ROUTING_MODE
EOF

In Cloud Shell, genera l'istanza di Secure Web Proxy:

gcloud network-services gateways import swp1 \
    --source=gateway.yaml \
    --location=us-central1

Il deployment di un Secure Web Proxy può richiedere diversi minuti.

e8a4cf23bfc63030.png

7. Collegamento di rete Private Service Connect

I collegamenti di rete sono risorse regionali che rappresentano il lato consumer di un'interfaccia Private Service Connect. Associ un'unica subnet a un collegamento di rete e il producer assegna gli IP all'interfaccia Private Service Connect da quella subnet. La subnet deve trovarsi nella stessa regione del collegamento di rete. Un collegamento di rete deve trovarsi nella stessa regione del servizio producer.

Crea il collegamento di rete

In Cloud Shell, crea il collegamento di rete.

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

Nota:non è necessario menzionare esplicitamente l'ID progetto accettato in questo allegato. Quando viene configurato il progetto tenant gestito da Google, Vertex AI viene aggiunto automaticamente come se fosse configurato su "Accetta automaticamente".

Elenca i collegamenti di rete

In Cloud Shell, elenca il collegamento di rete.

gcloud compute network-attachments list

Descrivi i collegamenti di rete

In Cloud Shell, descrivi il collegamento di rete.

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

Prendi nota del nome del collegamento di rete PSC, psc-network-attachment, che verrà utilizzato dal producer durante la creazione dell'interfaccia Private Service Connect.

Per visualizzare l'URL dell'allegato di rete PSC in Cloud Console, vai a:

Servizi di rete → Private Service Connect → Collegamento di rete → psc-network-attachment

b969cca5242d9c8a.png

8. Zona DNS privata

Creerai una zona Cloud DNS per demo.com e la compilerai con record A che rimandano agli indirizzi IP delle tue VM. In un secondo momento, il peering DNS verrà implementato nel job Vertex AI Pipelines, il che gli consentirà di accedere ai record DNS del consumer.

In Cloud Shell, esegui le seguenti operazioni:

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"

In Cloud Shell, crea il set di record per la VM, class-e-vm, assicurati di aggiornare l'indirizzo IP in base all'output del tuo ambiente.

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"

In Cloud Shell, crea il set di record per Secure Web Proxy, assicurati di aggiornare l'indirizzo IP in base all'output del tuo ambiente.

gcloud dns --project=$projectid record-sets create explicit-swp.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.5"

Crea una regola firewall cloud per consentire l'accesso dall'interfaccia PSC

Nella sezione seguente, crea una regola firewall che consenta al traffico proveniente dall'allegato di rete PSC di accedere alle risorse di calcolo RFC 1918 nel VPC dei consumer.

In Cloud Shell, crea la regola firewall in entrata che consente l'accesso dalla subnet solo proxy alla subnet di classe E. Poiché SWP avvia la connessione con la subnet solo proxy come indirizzo di origine.

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.100.0/28" \
    --destination-ranges="240.0.0.0/4" \
    --enable-logging

9. Crea un notebook Jupyter

La sezione seguente ti guida nella creazione di un blocco note Jupyter. Questo notebook verrà utilizzato per eseguire il deployment di un job di Vertex AI Pipelines che invia un wget da Vertex AI Pipelines alle istanze di test. Il percorso dei dati tra Vertex AI Pipelines e la rete consumer contenente le istanze utilizza un'interfaccia Private Service Connect.

Crea un service account gestito dall'utente

Nella sezione seguente creerai un service account che verrà associato all'istanza di Vertex AI Workbench utilizzata nel tutorial.

Nel tutorial, al service account verranno applicati i seguenti ruoli:

Accedi a Cloud Shell ed esegui le seguenti operazioni:

Crea il service account.

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

Aggiorna il service account con il ruolo Amministratore Storage.

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

Aggiorna il service account con il ruolo Utente AI Platform.

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

Aggiorna il service account con il ruolo Amministratore Artifact Registry.

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

Aggiorna il service account con il ruolo Editor Cloud Build.

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

Consenti al service account del notebook di utilizzare il service account Compute Engine predefinito.

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. Crea un'istanza di Vertex AI Workbench

Nella sezione seguente, crea un'istanza di Vertex AI Workbench che incorpori il service account creato in precedenza, notebook-sa.

In Cloud Shell, crea l'istanza client privata.

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. Aggiornamento di Vertex AI Service Agent

Vertex AI agisce per tuo conto per eseguire operazioni come l'ottenimento di un indirizzo IP dalla subnet di collegamento di rete PSC utilizzata per creare l'interfaccia PSC. A questo scopo, Vertex AI utilizza un service agent (elencato di seguito) che richiede l'autorizzazione Amministratore di rete.

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

Nota: prima di aggiornare le autorizzazioni dell'agente di servizio, vai a Vertex AI nella console Cloud per assicurarti che l'API Vertex AI sia abilitata.

In Cloud Shell:

Ottieni il numero di progetto.

gcloud projects describe $projectid | grep projectNumber

Imposta il numero del progetto.

projectnumber=YOUR-PROJECT-NUMBER

Crea un service account per AI Platform. Salta questo passaggio se hai un service account esistente nel tuo progetto.

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

Aggiorna l'account del service agent con il ruolo compute.networkAdmin.

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

Aggiorna l'account del service agent con il ruolo dns.peer

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

Aggiornamento del service account predefinito

Abilita l'API Compute Engine e concedi al service account predefinito l'accesso a Vertex AI. Tieni presente che la propagazione della modifica dell'accesso potrebbe richiedere un po' di tempo.

Utilizza Cloud Shell per aggiornare il service account predefinito nel seguente modo:

Aggiorna il service account predefinito con il ruolo aiplatform.user

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

Aggiorna il service account predefinito con il ruolo storage.admin

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

Aggiorna il service account predefinito con il ruolo artifactregistry.admin

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

12. Installa Apache2 e abilita Tcpdump su "class-e-vm":

Dall'class-e-vm installa apache2 tramite Secure Web Proxy:

Apri una nuova scheda di Cloud Shell, aggiorna la variabile del progetto ed esegui SSH nella VM class-e-vm

gcloud compute ssh --zone us-central1-a "class-e-vm" --tunnel-through-iap --project $projectid
sudo apt-get -o Acquire::http::Proxy="http://10.10.10.5:8080" update
sudo apt-get -o Acquire::http::Proxy="http://10.10.10.5:8080" install apache2 -y
sudo service apache2 restart
echo 'class-e Server !!' | sudo tee /var/www/html/index.html

Esegui il filtro tcpdump sulla subnet solo proxy, utilizzata da Secure Web Proxy per inoltrare il traffico alle destinazioni.

Dal sistema operativo class-e-vm esegui il filtro tcpdump sulla subnet proxy-vm.

sudo tcpdump -i any net 10.10.100.0/24 -nn

Nota: assicurati di attivare l'accesso privato Google nella subnet dell'istanza workbench-tutorial per aprire la sessione JupyterLab.

13. Esegui il deployment del job pipeline Vertex AI

Nella sezione seguente, creerai un notebook per eseguire un wget riuscito da Vertex AI Pipelines al proxy esplicito. In questo modo puoi raggiungere VM non RFC 1918, ad esempio class-e-vm. Non è necessario un proxy esplicito per consentire a Vertex AI Pipelines di accedere a rfc1918-vm, in quanto il target è un indirizzo IP RFC 1918.

Esegui il job di addestramento nell'istanza di Vertex AI Workbench.

  1. Nella console Google Cloud, vai alla scheda delle istanze nella pagina Vertex AI Workbench.
  2. Accanto al nome dell'istanza di Vertex AI Workbench (workbench-tutorial), fai clic su Apri JupyterLab. L'istanza di Vertex AI Workbench si apre in JupyterLab.
  3. Seleziona File > Nuovo > Notebook.
  4. Seleziona Kernel > Python 3.

Nel notebook JupyterLab, crea una nuova cella, aggiorna ed esegui quanto segue. Assicurati di aggiornare PROJECT_ID con i dettagli del tuo ambiente.

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)

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

# 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

Nel notebook JupyterLab, crea una nuova cella ed esegui la configurazione riportata di seguito. Tieni presente i seguenti punti salienti:

  • proxy_server = "http://explicit-swp.demo.com:8080"
  • Un FQDN è associato alla VM proxy di cui è stato eseguito il deployment nel VPC consumer. Utilizziamo il peering DNS per risolvere l'FQDN in un passaggio successivo.
%%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 nonRFC-1918 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://explicit-swp.demo.com:8080" # replace it with your Secure Web proxy Ip-address and the 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)

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

%%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"]

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice. Ignora l'errore (gcloud.builds.submit) se presente.

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

Nel notebook JupyterLab, crea ed esegui la cella seguente, prendendo nota dei seguenti punti salienti:

  • Il peering DNS con i VPC consumer viene configurato utilizzando dnsPeeringConfigs (dnsPeeringConfigs) per il nome di dominio demo.com.
  • Il proxy web in modalità di routing esplicito è explicit-swp.demo.com. La risoluzione viene gestita tramite il peering DNS all'interno del VPC del consumer.
  • La porta 8080 è la porta di ascolto (predefinita) configurata in Secure Web Proxy
  • wget a class-e-vm-demo.com viene risolto tramite il peering DNS
  • Il codice specifica "psc-network-attachment" per Vertex, consentendogli di utilizzare la subnet del collegamento di rete per eseguire il deployment di due istanze dell'interfaccia 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 = "explicit-swp.demo.com" #@param {type:"string"}
PROXY_VM_PORT = "8080" #@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))

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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)

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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)

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

# 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__))"

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

# 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"}

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

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")

Nel notebook JupyterLab, crea una nuova cella ed esegui il seguente codice.

# 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. Convalida dell'interfaccia PSC

Puoi anche visualizzare gli indirizzi IP di collegamento di rete utilizzati da Vertex AI Pipelines andando a:

Servizi di rete → Private Service Connect → Collegamento di rete → psc-network-attachment

Seleziona il progetto tenant (il nome del progetto termina con -tp)

a2e0b6d6243f26f1.png

Il campo evidenziato indica l'indirizzo IP utilizzato da Vertex AI Pipelines dall'allegato di rete PSC.

11e411ea919d3bad.png

15. Convalida di Cloud Logging

L'esecuzione del job Vertex AI Pipelines richiederà circa 14 minuti la prima volta, mentre le esecuzioni successive saranno molto più brevi. Per verificare l'esito positivo, esegui le seguenti operazioni:

Vai a Vertex AI → Addestramento → Job personalizzati

Seleziona il job personalizzato eseguito

2f467254aa0c2e3a.png

Seleziona Visualizza log.

8d525d3b152bcc61.png

Una volta disponibile Cloud Logging, seleziona Esegui query che genera la selezione evidenziata di seguito, che conferma un wget riuscito da Vertex AI Pipelines a class-e-vm.

a4f9e9167f4ce1ae.png

38972f834aa2bd1d.png

16. Convalida TCPDump

Esaminiamo l'output di TCPDUMP che convalida ulteriormente la connettività alle istanze di Compute:

A partire da class-e-vm, osserva HTTP GET e 200 OK

XXXXXXXXX@class-e-vm:~$ sudo tcpdump -i any net 10.10.100.0/28 -nn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
05:51:14.173641 ens4  In  IP 10.10.100.8.55306 > 240.0.0.2.80: Flags [S], seq 1747181041, win 65535, options [mss 1420,sackOK,TS val 3942828403 ecr 0,nop,wscale 8], length 0
05:51:14.173668 ens4  Out IP 240.0.0.2.80 > 10.10.100.8.55306: Flags [S.], seq 3013226100, ack 1747181042, win 64768, options [mss 1420,sackOK,TS val 1886125065 ecr 3942828403,nop,wscale 7], length 0
05:51:14.174977 ens4  In  IP 10.10.100.8.55306 > 240.0.0.2.80: Flags [.], ack 1, win 1054, options [nop,nop,TS val 3942828405 ecr 1886125065], length 0
05:51:14.175066 ens4  In  IP 10.10.100.8.55306 > 240.0.0.2.80: Flags [P.], seq 1:223, ack 1, win 1054, options [nop,nop,TS val 3942828405 ecr 1886125065], length 222: HTTP: GET / HTTP/1.1
05:51:14.175096 ens4  Out IP 240.0.0.2.80 > 10.10.100.8.55306: Flags [.], ack 223, win 505, options [nop,nop,TS val 1886125066 ecr 3942828405], length 0
05:51:14.239042 ens4  Out IP 240.0.0.2.80 > 10.10.100.8.55306: Flags [P.], seq 1:246, ack 223, win 505, options [nop,nop,TS val 1886125130 ecr 3942828405], length 245: HTTP: HTTP/1.1 200 OK

17. Esegui la pulizia

Da Cloud Shell, elimina i componenti del tutorial.

gcloud workbench instances delete workbench-tutorial --project=$projectid --location=us-central1-a

gcloud network-security gateway-security-policies rules delete allow-nonrfc-classe \
    --gateway-security-policy=policy1 \
    --location=us-central1

gcloud network-security gateway-security-policies rules delete allow-apache2 \
    --gateway-security-policy=policy1 \
    --location=us-central1

gcloud network-security gateway-security-policies delete policy1 \
    --location=us-central1
gcloud network-services gateways delete swp1 \
    --location=us-central1

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 explicit-swp.demo.com --zone=private-dns-codelab  --type=A

gcloud dns managed-zones delete private-dns-codelab

gcloud computeinstances delete class-e-vm --project=$projectid --zone=us-central1-a --quiet
gcloud compute networks delete consumer-vpc --quiet

18. Complimenti

Congratulazioni, hai configurato e convalidato correttamente una connessione tra l'interfaccia Private Service Connect di Vertex AI Pipelines e intervalli IP non RFC tramite Secure Web Proxy.

Hai creato l'infrastruttura consumer e hai aggiunto un collegamento di rete che ha consentito al producer di creare una VM con più NIC per collegare la comunicazione tra consumer e producer. Hai imparato a creare il peering DNS durante il deployment di un proxy esplicito nella rete VPC consumer che consentiva la connettività all'istanza class-e-vm non instradabile direttamente da Vertex AI.

678ba30d64a76795.png

Passaggi successivi

Ulteriori letture e video

Documentazione di riferimento