1. Introdução
A interface do Private Service Connect é um recurso que permite que uma rede de nuvem privada virtual (VPC, na sigla em inglês) do produtor inicie conexões com vários destinos em uma rede VPC do consumidor. As redes de produtor e consumidor podem estar em diferentes projetos e organizações.
Se um anexo de rede aceitar uma conexão de uma interface do Private Service Connect, o Google Cloud alocará à interface um endereço IP de uma sub-rede do consumidor especificada pelo anexo de rede. As redes de consumidores e produtores estão conectadas e podem se comunicar por endereços IP internos.
Uma conexão entre um anexo de rede e uma interface do Private Service Connect é semelhante à conexão entre um endpoint do Private Service Connect e um anexo de serviço, mas há duas diferenças principais:
- Um anexo de rede permite que uma rede produtora inicie conexões com uma rede consumidora (saída de serviço gerenciada), enquanto um endpoint permite que uma rede consumidora inicie conexões com uma rede produtora (entrada de serviço gerenciada).
- Uma conexão de interface do Private Service Connect é transitiva. Isso significa que uma rede do produtor pode se comunicar com outras que estão conectadas à rede do consumidor.
Considerações sobre a acessibilidade da interface do PSC da Vertex AI
- A interface do PSC pode rotear o tráfego para destinos baseados em VPC ou locais no bloco de endereços RFC1918.
- O direcionamento de interface do PSC a blocos de endereços não rfc-1918 exige um proxy explícito implantado na VPC do consumidor com um endereço rfc-1918. Na implantação da Vertex AI, o proxy precisa ser definido com um FQDN do endpoint de destino. Consulte a Figura 1, que representa o proxy explícito configurado nas VPCs dos clientes para facilitar o roteamento para os seguintes CIDRs não RFC-1918:
[1] 240.0.0.0/4
[2] 203.0.113.0/2
[3]10.10.20.0/28 não requer proxy, está no intervalo rfc1918.
- Quando você configura a implantação apenas com uma interface do PSC, ela mantém o acesso padrão à Internet. Esse tráfego de saída sai diretamente da rede de locatário segura e gerenciada pelo Google.
Considerações sobre a VPC-SC da interface PSC da Vertex AI
- Quando seu projeto faz parte de um perímetro do VPC Service Controls, o acesso padrão à Internet dos tenants gerenciados pelo Google é bloqueado pelo perímetro para evitar a exfiltração de dados.
- Para permitir que a implantação acesse a Internet pública nesse cenário, configure explicitamente um caminho de saída seguro que roteie o tráfego pela sua VPC. A maneira recomendada de fazer isso é configurar um servidor proxy dentro do perímetro da VPC com um endereço RFC1918 e criar um gateway do Cloud NAT para permitir que a VM proxy acesse a Internet.
Para mais informações, consulte os seguintes recursos:
Configurar uma interface do Private Service Connect para recursos da Vertex AI | Google Cloud
O que você vai criar
Neste tutorial, você vai criar uma implantação abrangente do Vertex AI Pipelines com a interface do Private Service Connect (PSC) para permitir a conectividade do produtor com a computação do consumidor, conforme ilustrado na Figura 1, segmentando endpoints não RFC-1928.
Figura 2.
Você vai criar um único psc-network-attachment na VPC do consumidor usando o peering de DNS para resolver as VMs do consumidor no projeto do locatário que hospeda o Vertex AI Training, resultando nos seguintes casos de uso:
- Implante o Vertex AI Pipelines e configure uma VM proxy para atuar como um proxy explícito, permitindo que ela execute um wget em uma VM na sub-rede de classe E.
O que você vai aprender
- Como criar um anexo de rede
- Como um produtor pode usar um anexo de rede para criar uma interface do PSC
- Como estabelecer comunicação do produtor para o consumidor usando o peering de DNS
- Como estabelecer comunicação com o espaço de endereços IP não rfc1918 do Vertex AI Pipelines
O que é necessário
Projeto do Google Cloud
Permissões do IAM
- Administrador de rede do Compute (roles/compute.networkAdmin)
- Administrador de instâncias do Compute (roles/compute.instanceAdmin)
- Administrador de segurança do Compute (roles/compute.securityAdmin)
- Administrador do DNS (roles/dns.admin)
- Usuário do túnel protegido pelo IAP (roles/iap.tunnelResourceAccessor)
- Administrador do Logging (roles/logging.admin)
- Administrador do Notebooks (roles/notebooks.admin)
- Administrador do IAM do projeto (roles/resourcemanager.projectIamAdmin)
- Administrador da conta de serviço (roles/iam.serviceAccountAdmin)
- Administrador do Service Usage (roles/serviceusage.serviceUsageAdmin)
2. Antes de começar
Atualizar o projeto para oferecer suporte ao tutorial
Este tutorial usa $variables para ajudar na implementação da configuração do gcloud no Cloud Shell.
No Cloud Shell, faça o seguinte:
gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid
Ativação da API
No Cloud Shell, faça o seguinte:
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. Configuração do consumidor
Criar a VPC do consumidor
No Cloud Shell, faça o seguinte:
gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom
Criar as sub-redes do consumidor
No Cloud Shell, faça o seguinte:
gcloud compute networks subnets create class-e-subnet --project=$projectid --range=240.0.0.0/4 --network=consumer-vpc --region=us-central1
No Cloud Shell, faça o seguinte:
gcloud compute networks subnets create rfc1918-subnet1 --project=$projectid --range=10.10.10.0/28 --network=consumer-vpc --region=us-central1
Criar a sub-rede de anexo de rede do Private Service Connect
No Cloud Shell, faça o seguinte:
gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1
Configuração do Cloud Router e do NAT
Neste tutorial, o Cloud NAT é usado para fornecer acesso à Internet à VM de proxy, que não tem um endereço IP público. O Cloud NAT permite que VMs com apenas endereços IP particulares se conectem à Internet, permitindo que elas executem tarefas como instalar pacotes de software.
No Cloud Shell, crie o Cloud Router.
gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1
No Cloud Shell, crie o gateway 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. Ativar o IAP
Para permitir que o IAP se conecte às suas instâncias de VM, crie uma regra de firewall que:
- Aplica-se a todas as instâncias de VM que você quer acessar usando o IAP.
- Permite o tráfego de entrada do intervalo de IP 35.235.240.0/20. Esse intervalo contém todos os endereços IP que o IAP usa para o encaminhamento de TCP.
No Cloud Shell, crie a regra de firewall do IAP.
gcloud compute firewall-rules create ssh-iap-consumer \
--network consumer-vpc \
--allow tcp:22 \
--source-ranges=35.235.240.0/20
5. Criar instâncias de VM do consumidor
No Cloud Shell, crie a instância de VM do consumidor, 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"
No Cloud Shell, crie a instância de VM do consumidor, proxy-vm, que vai servir como proxy explícito para o Vertex AI Pipelines. Vamos usar o tinyproxy como o aplicativo para proxy do tráfego HTTP, embora o HTTPS também seja compatível.
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. Anexo de rede do Private Service Connect
Os anexos de rede são recursos regionais que representam o lado do consumidor de uma interface do Private Service Connect. Você associa uma única sub-rede a um anexo de rede, e o produtor atribui IPs à interface do Private Service Connect a partir dessa sub-rede. A sub-rede precisa estar na mesma região do anexo de rede. Um anexo de rede precisa estar na mesma região do serviço do produtor.
Criar o anexo de rede
No Cloud Shell, crie o anexo de rede.
gcloud compute network-attachments create psc-network-attachment \
--region=us-central1 \
--connection-preference=ACCEPT_AUTOMATIC \
--subnets=intf-subnet
Listar os anexos de rede
No Cloud Shell, liste o anexo de rede.
gcloud compute network-attachments list
Descrever os anexos de rede
No Cloud Shell, descreva o anexo de rede.
gcloud compute network-attachments describe psc-network-attachment --region=us-central1
Anote o nome psc-network-attachment, psc-network-attachment, que será usado pelo produtor ao criar a interface do Private Service Connect.
Para ver o URL de anexo de rede do PSC no console do Cloud, navegue até:
Serviços de rede → Private Service Connect → Anexo de rede → psc-network-attachment
7. Zona de DNS particular
Você vai criar uma zona do Cloud DNS para demo.com e preenchê-la com registros A que apontam para os endereços IP das suas VMs. Mais tarde, o peering de DNS será implantado no job do Vertex AI Pipelines, o que permitirá o acesso aos registros DNS do consumidor.
No Cloud Shell, faça o seguinte:
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"
No Cloud Shell, execute uma descrição nas instâncias de VM para receber os respectivos endereços IP.
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:
No Cloud Shell, crie o conjunto de registros para a VM, class-e-vm, e atualize o endereço IP com base na saída do seu 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"
No Cloud Shell, crie o conjunto de registros para a VM, proxy-vm, e atualize o endereço IP com base na saída do seu ambiente.
gcloud dns --project=$projectid record-sets create proxy-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.2"
Criar uma regra do Cloud Firewall para permitir o acesso da interface do PSC
Na seção a seguir, crie uma regra de firewall que permita o tráfego originado do acesso ao anexo de rede do PSC a recursos de computação RFC1918 na VPC dos consumidores.
No Cloud Shell, crie a regra de firewall de entrada que permite o acesso da sub-rede de anexo de rede do PSC à proxy-vm.
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
No Cloud Shell, crie a regra de firewall de entrada que permite o acesso da sub-rede proxy-vm à sub-rede class-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. Atualizar o proxy explícito
Na seção a seguir, você precisará fazer SSH no proxy explícito e atualizar o arquivo de configuração tinyproxy.conf, seguido de uma redefinição.
No Cloud Shell
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Abra o arquivo de configuração do tinyproxy e atualize usando um editor de sua escolha. Confira um exemplo usando o 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. Crie um notebook do Jupyter
A seção a seguir orienta você na criação de um notebook do Jupyter. Este notebook será usado para implantar um job do Vertex AI Pipelines que envia um wget do Vertex AI Pipelines para as instâncias de teste. O caminho de dados entre o Vertex AI Pipelines e a rede do consumidor que contém as instâncias usa uma interface de rede do Private Service Connect.
Criar uma conta de serviço gerenciada pelo usuário
Na seção a seguir, você vai criar uma conta de serviço que será associada à instância do Vertex AI Workbench usada no tutorial.
No tutorial, a conta de serviço terá as seguintes funções aplicadas:
- Administrador do Storage
- Usuário da Vertex AI
- Administrador do Artifact Registry
- Editor do Cloud Build
- Usuário da conta de serviço do IAM
No Cloud Shell, crie a conta de serviço.
gcloud iam service-accounts create notebook-sa \
--display-name="notebook-sa"
No Cloud Shell, atualize a conta de serviço com o papel de administrador do Storage.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"
No Cloud Shell, atualize a conta de serviço com o papel de usuário da Vertex AI.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"
No Cloud Shell, atualize a conta de serviço com o papel Administrador do Artifact Registry.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"
No Cloud Shell, atualize a conta de serviço com o papel de editor do Cloud Build.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/cloudbuild.builds.editor"
No Cloud Shell, permita que a conta de serviço do notebook use a conta de serviço padrão do Compute Engine.
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. criar uma instância do Vertex AI Workbench
Na seção a seguir, crie uma instância do Vertex AI Workbench que incorpore a conta de serviço criada anteriormente, notebook-sa.
No Cloud Shell, crie a instância private-client.
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. Atualização do agente de serviço da Vertex AI
A Vertex AI age em seu nome para realizar operações como a obtenção de um endereço IP da sub-rede de anexo de rede do PSC usada para criar a interface do PSC. Para isso, a Vertex AI usa um agente de serviço (listado abaixo) que exige a permissão de administrador de rede.
service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com
No Cloud Shell, recupere o número do projeto.
gcloud projects describe $projectid | grep projectNumber
No Cloud Shell, recupere o número do projeto.
gcloud projects describe $projectid | grep projectNumber
projectNumber: '234086459238'
No Cloud Shell, defina o número do projeto.
projectnumber=YOUR-PROJECT-Number
No Cloud Shell, crie uma conta de serviço para o AI Platform. Pule esta etapa se você já tiver uma conta de serviço no projeto.
gcloud beta services identity create --service=aiplatform.googleapis.com --project=$projectnumber
No Cloud Shell, atualize a conta do agente de serviço com a função compute.networkAdmin.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/compute.networkAdmin"
No Cloud Shell, atualize a conta do agente de serviço com a função dns.peer
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/dns.peer"
Atualização da conta de serviço padrão
Ative a API Compute Engine e conceda à sua conta de serviço padrão acesso à Vertex AI. Pode levar algum tempo para a mudança no acesso ser propagada.
No Cloud Shell, atualize a conta de serviço padrão com a função aiplatform.user
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/aiplatform.user"
No Cloud Shell, atualize a conta de serviço padrão com o papel storage.admin.
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/storage.admin"
No Cloud Shell, atualize a conta de serviço padrão com o papel storage.admin.
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.admin"
12. Ativar o Tcpdump
Para validar a conectividade IP do Vertex AI Pipelines, podemos usar o TCPDUMP. Isso vai permitir observar a comunicação originada da sub-rede de anexo de rede do PSC, 192.168.10.0/28, ao invocar a solicitação GET dos Pipelines da Vertex AI para a VM, class-e-vm.demo.com (240.0.0.0/4).
No Cloud Shell, conecte-se via SSH à VM de proxy.
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
No SO da proxy-vm, execute a filtragem tcpdump na sub-rede de anexo de rede class-e-vm e PSC.
sudo tcpdump -i any net 240.0.0.0/4 or 192.168.10.0/28 -nn
Abra uma nova guia do Cloud Shell, atualize a variável do projeto e faça ssh na class-e-vm
gcloud compute ssh --zone us-central1-a "class-e-vm" --tunnel-through-iap --project $projectid
No SO da VM class-e-vm, execute a filtragem tcpdump na sub-rede proxy-vm.
sudo tcpdump -i any net 10.10.10.0/28 -nn
13. Implantar um job do Vertex AI Pipelines
Na seção a seguir, você vai criar um notebook para realizar um wget bem-sucedido da Vertex AI Pipelines para o proxy explícito. Isso permite alcançar VMs não RFC 1918, como a class-e-vm. Um proxy explícito não é necessário para que o Vertex AI Pipelines acesse rfc1918-vm, já que o destino é um endereço IP RFC 1918.
Execute o job de treinamento na instância do Vertex AI Workbench.
- No console do Google Cloud, acesse a guia "Instâncias" na página do Vertex AI Workbench.
- Ao lado do nome da instância do Vertex AI Workbench (workbench-tutorial), clique em "Abrir JupyterLab". A instância do Vertex AI Workbench será aberta no JupyterLab.
- Selecione Arquivo > Novo > Notebook.
- Selecione Kernel > Python 3
No notebook do JupyterLab, crie uma célula e execute o seguinte:
# 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
No notebook do JupyterLab, crie uma nova célula, atualize e execute o seguinte. Atualize PROJECT_ID com os detalhes do seu 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)
No notebook do JupyterLab, crie uma célula e execute o seguinte:
# 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
No notebook do JupyterLab, crie uma nova célula e execute a configuração abaixo. Observe os seguintes destaques:
- proxy_server = "http://proxy-vm.demo.com:8888" O FQDN está associado à VM de proxy implantada na VPC do consumidor. Estamos usando o peering de DNS para resolver o FQDN em uma etapa posterior.
%%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)
No notebook do JupyterLab, crie uma célula e execute o seguinte:
%%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"]
No notebook do JupyterLab, crie uma célula e execute o seguinte:
!gcloud artifacts repositories create pipelines-test-repo-psc --repository-format=docker --location=us-central1
No notebook do JupyterLab, crie uma célula e execute o seguinte:
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
No notebook do JupyterLab, crie uma célula e execute o seguinte:
!gcloud auth configure-docker us-docker.pkg.dev --quiet
No notebook do JupyterLab, crie uma célula e execute o seguinte: Ignore o erro (gcloud.builds.submit) se ele aparecer.
!gcloud builds submit --tag {IMAGE_URI} --region=us-central1
No notebook do JupyterLab, crie e execute a célula abaixo. Observe os seguintes destaques:
- O peering de DNS para VPCs consumidoras é configurado usando dnsPeeringConfigs (dnsPeeringConfigs) para o nome de domínio demo.com.
- O proxy explícito, definido como a variável PROXY_VM_IP, é proxy-vm.demo.com. A resolução é processada pelo peering de DNS na VPC do consumidor.
- A porta 8888 é a porta de escuta (padrão) configurada no tinyproxy.
- O Wget para class-e-vm-demo.com é resolvido por peering de DNS.
- O código especifica o "psc-network-attachment" para o Vertex, permitindo que ele use a sub-rede de anexo de rede para implantar duas instâncias de interface do 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))
No notebook do JupyterLab, crie uma célula e execute o seguinte:
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)
No notebook do JupyterLab, crie uma célula e execute o seguinte:
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)
No notebook do JupyterLab, crie uma célula e execute o seguinte:
# 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__))"
No notebook do JupyterLab, crie uma célula e execute o seguinte:
BUCKET_URI = "your-unique-bucket" # Provide a globally unique bucket name
No notebook do JupyterLab, crie uma célula e execute o seguinte:
!gcloud storage buckets create gs://{BUCKET_URI}
No notebook do JupyterLab, crie uma célula e execute o seguinte:
# 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"}
No notebook do JupyterLab, crie uma célula e execute o seguinte:
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")
No notebook do JupyterLab, crie uma célula e execute o seguinte:
# 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. Validação da interface do PSC
Também é possível conferir os IPs de anexação de rede usados pelo Vertex AI Pipelines navegando até:
Serviços de rede → Private Service Connect → Anexo de rede → psc-network-attachment
Selecione o projeto do locatário (nome do projeto que termina em -tp).
O campo destacado indica o endereço IP usado pelo Vertex AI Pipelines no anexo de rede PSC.
15. Validação do Cloud Logging
O job do Vertex AI Pipelines leva cerca de 14 minutos para ser executado pela primeira vez. As execuções subsequentes são muito mais rápidas. Para validar um resultado positivo, faça o seguinte:
Acesse Vertex AI → Treinamento → Jobs personalizados
Selecione o job personalizado executado.
Selecione "Ver registros"
Quando o Cloud Logging estiver disponível, selecione "Executar consulta", que gera a seleção destacada abaixo e confirma um wget bem-sucedido dos Pipelines da Vertex AI para a classe-e-vm.
16. Validação do TCPDump
Vamos analisar a saída do TCPDUMP que valida ainda mais a conectividade com instâncias de computação:
Na proxy-vm, observe o HTTP GET e 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
Da classe-e-vm, observe o HTTP GET e 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. Limpar
No Cloud Shell, exclua os componentes do tutorial.
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. Parabéns
Parabéns, você configurou e validou uma interface do Private Service Connect com o Vertex AI Pipelines.
Você criou a infraestrutura do consumidor e adicionou um anexo de rede que permitiu ao produtor criar uma VM de várias NICs para fazer a ponte entre a comunicação do consumidor e do produtor. Você aprendeu a criar um peering de DNS ao implantar um proxy explícito na rede VPC do consumidor, o que permitiu a conectividade com a instância de VM de classe E que não pode ser roteada diretamente do Vertex.
A Cosmopup acha que os tutoriais são incríveis!
Qual é a próxima etapa?
Leituras e vídeos complementares
Documentos de referência
- Visão geral do acesso à rede da Vertex AI | Google Cloud
- Como acessar os serviços da Vertex AI usando interfaces do Private Service Connect | Google Cloud
- Usar a interface do Private Service Connect para o Vertex AI Training | Google Cloud
- Configurar uma interface do Private Service Connect para recursos da Vertex AI | Google Cloud