Integration von Agent Engine (ADK) in PSC SWP

1. Einführung

Eine Private Service Connect-Schnittstelle ist eine Ressource, mit der das VPC-Netzwerk (Virtual Private Cloud) eines Erstellers Verbindungen zu verschiedenen Zielen in einem Nutzer-VPC-Netzwerk initiieren kann. Ersteller- und Nutzernetzwerke können sich in verschiedenen Projekten und Organisationen befinden.

Wenn ein Netzwerkanhang eine Verbindung von einer Private Service Connect-Schnittstelle akzeptiert, weist Google Cloud der Schnittstelle eine IP-Adresse aus einem vom Netzwerkanhang bestimmten Nutzersubnetz zu. Die Nutzer- und Erstellernetzwerke sind verbunden und können über interne IP-Adressen kommunizieren.

Eine Verbindung zwischen einem Netzwerkanhang und einer Private Service Connect-Schnittstelle ähnelt der Verbindung zwischen einem Private Service Connect-Endpunkt und einem Dienstanhang, weist aber zwei wichtige Unterschiede auf:

  • Mit einem Netzwerkanhang kann ein Erstellernetzwerk Verbindungen zu einem Nutzernetzwerk initiieren (verwalteter ausgehender Dienst), während ein Endpunkt es einem Nutzernetzwerk ermöglicht, Verbindungen zu einem Erstellernetzwerk zu initiieren (verwalteter Dienst).
  • Private Service Connect-Schnittstellenverbindungen sind transitiv. Dies bedeutet, dass ein Erstellernetzwerk mit anderen Netzwerken kommunizieren kann, die mit dem Nutzernetzwerk verbunden sind.

Überlegungen zur Erreichbarkeit von Vertex AI-PSC-Schnittstellen

  • Die PSC-Schnittstelle kann Traffic an VPC- oder lokale Ziele weiterleiten, die vom VPC-Netzwerk gelernt wurden.
  • Um den Bereich der Erreichbarkeit über die vom Agent Engine verwendeten Netzwerkverbindung auf das VPC-Netzwerk zu beschränken, ist die Implementierung von Firewallregeln für ausgehenden Traffic die beste Vorgehensweise.
  • Um den Umfang des ausgehenden Netzwerk-Traffics aus dem Subnetz für die Netzwerkverbindung der Agent Engine zu begrenzen, sollte eine VPC-Firewallregel für ausgehenden Traffic bereitgestellt werden. Mit dieser Regel wird Traffic von der Agent Engine zur SWP explizit zugelassen, während der gesamte andere ausgehende Traffic abgelehnt wird.

VPC-SC-Überlegungen zur Vertex AI-PSC-Schnittstelle

  • Sie müssen in der Kunden-VPC eine Internet-Egress-Verbindung für die Funktion der Agent Engine-PSC-Schnittstelle bereitstellen, auch wenn VPC Service Controls aktiviert sind.

Sicherer Web-Proxy

Secure Web Proxy ist ein verwalteter, cloudnativer Dienst, mit dem Sie ausgehenden Traffic (HTTP/HTTPS) detailliert steuern und schützen können. Es fungiert als zentrales Gateway, mit dem Sie Sicherheitsrichtlinien für Verbindungen erzwingen können, die von Agent Engine initiiert werden, die mit PSC-Schnittstelle für VPC-Ressourcen wie VMs, GKE, Internet und Multi-Cloud-Umgebungen bereitgestellt wird.

Was wird damit gelöst?

  • Verhindert Daten-Exfiltration:Unbefugte Uploads oder die Kommunikation mit schädlichen Websites werden blockiert.
  • Compliance wird erzwungen:Ausgehender Traffic entspricht den Sicherheits- und Datenverarbeitungsrichtlinien Ihrer Organisation.
  • Reduziert den Betriebsaufwand:Da Secure Web Proxy ein vollständig verwalteter Dienst ist, müssen Sie keine eigenen Proxy-VMs bereitstellen, skalieren oder verwalten.
  • Umfassende Transparenz:Ermöglicht die Prüfung von mit Transport Layer Security (TLS) verschlüsseltem Traffic, um verborgene Bedrohungen zu erkennen.

Weitere Informationen finden Sie in den folgenden Ressourcen:

KI-Agent bereitstellen | Generative KI in Vertex AI | Google Cloud

Private Service Connect-Schnittstelle für Vertex AI-Ressourcen einrichten | Google Cloud

Aufgaben

In dieser Anleitung erstellen Sie eine umfassende Agent Engine, die mit einer Private Service Connect-Schnittstelle (PSC) bereitgestellt und in SWP integriert wird, um mit ADK-Bibliotheken Folgendes auszuführen:

  • Stellen Sie DNS-Peering in Agent Engine bereit, um den vollständig qualifizierten Domainnamen des SWP aufzulösen, der in der Proxykonfiguration verwendet wird.
  • Verbindungen zu einer öffentlichen Website (https://api.frankfurter.app/) über einen Secure Web Proxy zulassen, der in der VPC des Nutzers mit einer RFC1918-Adresse bereitgestellt wird.
  • Lassen Sie Traffic vom Network Attachment-Subnetz zum SWP zu, lehnen Sie aber alles andere ab.

Abbildung 1

565e9eb07ef18f44.png

Lerninhalte

  • Netzwerkanhang erstellen
  • So kann ein Produzent einen Netzwerkanhang verwenden, um eine PSC-Schnittstelle zu erstellen
  • Kommunikation vom Produzenten zum Nutzer über DNS-Peering einrichten
  • SWP für Internet-Egress bereitstellen und verwenden
  • Firewallregeln für ausgehenden Traffic definieren, um die Netzwerkverfügbarkeit von Agent Engine zu verringern

Voraussetzungen

Google Cloud-Projekt

IAM-Berechtigungen

2. Hinweis

Projekt für das Tutorial aktualisieren

In dieser Anleitung werden $variables verwendet, um die Implementierung der gcloud-Konfiguration in Cloud Shell zu erleichtern.

Führen Sie in Cloud Shell folgende Schritte aus:

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

API-Aktivierung

Führen Sie in Cloud Shell folgende Schritte aus:

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

Prüfen, ob die APIs aktiviert wurden

gcloud services list --enabled

3. Einrichtung durch Nutzer

Consumer-VPC erstellen

Diese VPC befindet sich in einem Kundenprojekt. Die folgenden Ressourcen werden in dieser VPC erstellt:

  • Consumer-Subnetz
  • Subnetz für Netzwerkanhang
  • Nur-Proxy-Subnetz
  • Firewallregeln
  • Cloud DNS

Führen Sie in Cloud Shell folgende Schritte aus:

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

Nutzer-Subnetze erstellen

Erstellen Sie in Cloud Shell das Subnetz für den SWP:

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

Subnetz für den Private Service Connect-Netzwerkanhang erstellen

Erstellen Sie in Cloud Shell das Subnetz für die PSC-Netzwerkverbindung:

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

Regionales Proxy-Subnetz erstellen

Erstellen Sie in Cloud Shell das Nur-Proxy-Subnetz, das für Envoy-basierte Produkte wie Secure Web Proxy und regionale interne/externe Application Load Balancer erforderlich ist. Das Flag „–purpose“ muss auf REGIONAL_MANAGED_PROXY gesetzt sein:

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

Notebook-Subnetz erstellen

Erstellen Sie in Cloud Shell das Subnetz für die Notebook-Instanz:

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

4. Secure Web Proxy erstellen

Der explizite Modus (oder explizite Proxy-Routing-Modus) von Secure Web Proxy ist eine Bereitstellungsmethode, bei der die Clientarbeitslasten explizit so konfiguriert werden müssen, dass sie die interne IP-Adresse oder den vollqualifizierten Domainnamen und den Port von SWP als Weiterleitungs-Proxy verwenden.

Diese Richtlinie enthält die Regeln, die den Traffic über den sicheren Web-Proxy auf Grundlage eines Sitzungsabgleichs, host() == 'api.frankfurter.app' und eines Anwendungsabgleichs request.method == 'GET' steuern.

Achten Sie darauf, dass Sie in den folgenden Schritten YOUR-PROJECT-ID durch Ihre Projekt-ID ersetzen.

Erstellen Sie in Cloud Shell eine policy.yaml-Datei:

cat > policy.yaml << EOF
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/my-swp-policy 
description: "My basic SWP policy" 
EOF

Importieren Sie die Richtlinie in Cloud Shell:

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

Secure Web Proxy-Regeln erstellen

Definieren Sie Regeln in der Richtlinie, um festzulegen, welcher Traffic zugelassen oder abgelehnt wird. Regeln werden nach Priorität ausgewertet.

Erstellen Sie in Cloud Shell eine „rule.yaml“-Datei, um den Zugriff auf den vom Agent-Engine verwendeten Internetendpunkt „api.frankfurter.app“ zuzulassen:

cat > rule.yaml << EOF
name: "projects/$projectid/locations/us-central1/gatewaySecurityPolicies/my-swp-policy/rules/allow-example"
description: "Allow frankfurter API"
enabled: true
priority: 10
basicProfile: ALLOW
sessionMatcher: "host() == 'api.frankfurter.app'"
EOF

Generieren Sie in Cloud Shell eine Sicherheitsrichtlinienregel:

gcloud network-security gateway-security-policies rules import allow-example \
    --source=rule.yaml \
    --location=us-central1 \
    --gateway-security-policy=my-swp-policy

Secure Web Proxy-Regeln erstellen

Die SWP-Instanz, die im expliziten Routingmodus bereitgestellt wird, muss so erstellt werden, dass die Agent Engine die IP-Adresse oder den FQDN der SWP in der ADK-Proxykonfiguration angeben muss, wie in der Gateway-YAML-Datei definiert. Durch diese Konfiguration wird die Instanz auch mit der entsprechenden Richtlinie, dem entsprechenden Netzwerk und dem entsprechenden Subnetz verknüpft.

Erstellen Sie in Cloud Shell eine gateway.yaml-Datei, mit der das SWP bereitgestellt wird.

Speichern Sie die YAML-Datei, nachdem Sie die folgenden Variablen mit den Details Ihrer Umgebung aktualisiert haben: PROJECT_ID, REGION, NETWORK_NAME und PROXY_ONLY_SUBNET_NAME. Der angegebene Port 8888 ist der äußere Tunnelport, der der Proxykonfiguration in Agent Engine zugeordnet ist.

cat > gateway.yaml << EOF
name: "projects/$projectid/locations/us-central1/gateways/my-swp-instance"
type: SECURE_WEB_GATEWAY
ports: [8888]
addresses: ["10.10.10.5"]
gatewaySecurityPolicy: "projects/$projectid/locations/us-central1/gatewaySecurityPolicies/my-swp-policy"
network: "projects/$projectid/global/networks/consumer-vpc"
subnetwork: "projects/$projectid/regions/us-central1/subnetworks/swp-subnet"
routingMode: EXPLICIT_ROUTING_MODE
EOF

Importieren Sie das Gateway in Cloud Shell:

gcloud network-services gateways import my-swp-instance \
    --source=gateway.yaml \
    --location=us-central1

5. Private Service Connect-Netzwerkanhang

Netzwerkanhänge sind regionale Ressourcen, die die Nutzerseite einer Private Service Connect-Schnittstelle darstellen. Sie verknüpfen ein einzelnes Subnetz mit einem Netzwerkanhang und der Ersteller weist der Private Service Connect-Schnittstelle IP-Adressen aus diesem Subnetz zu. Das Subnetz muss sich in derselben Region wie der Netzwerkanhang befinden. Netzwerkanhänge müssen sich in derselben Region wie deren Produzentendienst befinden.

Netzwerkanhang erstellen

Erstellen Sie den Netzwerkanhang in Cloud Shell.

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

Netzwerkanhänge auflisten

Listen Sie die Netzwerkverbindung in Cloud Shell auf.

gcloud compute network-attachments list

Netzwerkanhänge beschreiben

Beschreiben Sie den Netzwerkanhang in Cloud Shell.

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

Notieren Sie sich den Namen des PSC-Netzwerkanhangs, psc-network-attachment, der vom Ersteller beim Erstellen der Private Service Connect-Schnittstelle verwendet wird.

So rufen Sie die URL für die PSC-Netzwerkverbindung in der Cloud Console auf:

Network Services → Private Service Connect → Network Attachment → psc-network-attachment

15f80b46c3a0332d.png

6. Private DNS-Zone

Sie erstellen eine Cloud DNS-Zone für demo.com und füllen sie mit einem A-Eintrag, der auf die IP-Adressen Ihrer SWPs verweist. Später wird DNS-Peering in Agent Engine bereitgestellt, wodurch der Zugriff auf die DNS-Einträge des Nutzers möglich wird.

Führen Sie in Cloud Shell die folgenden Schritte aus, um den DNS-Namen „demo.com“ zu erstellen.

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"

Rufen Sie die IP-Adressen des SWP ab, die für den DNS-A-Eintrag verwendet werden, und speichern Sie sie.

Führen Sie in Cloud Shell einen „describe“-Befehl für die SWP „my-swp-instance“ aus:

gcloud network-services gateways describe my-swp-instance --location=us-central1

Erstellen Sie in Cloud Shell den Datensatz für die SWP, swp.demo.com. Achten Sie darauf, die IP-Adresse entsprechend der Ausgabe Ihrer Umgebung zu aktualisieren.

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

Firewallkonfiguration

Cloud Firewall-Regel erstellen, um den Zugriff über die PSC-Schnittstelle zuzulassen

Erstellen Sie im folgenden Abschnitt eine Firewallregel, die Traffic, der vom PSC-Netzwerkanhang stammt, den Zugriff auf das SWP-Subnetz in der Consumer-VPC ermöglicht. Für eine erhöhte Sicherheit können Sie die SWP-IP-Adresse als einziges Ziel angeben.

Erstellen Sie in Cloud Shell die Firewallregel für ausgehenden Traffic, die den Zugriff vom Netzwerk-Attachment auf den SWP ermöglicht:

gcloud compute firewall-rules create allow-access-to-swp \
    --network=consumer-vpc \
    --action=ALLOW \
    --rules=ALL \
    --direction=EGRESS \
    --priority=1000 \
    --source-ranges="192.168.10.0/28" \
    --destination-ranges="10.10.10.5/32" \
    --enable-logging

Erstellen Sie in Cloud Shell die Firewallregel für ausgehenden Traffic, die den gesamten Traffic von der Netzwerkverbindung ablehnt:

gcloud compute firewall-rules create deny-all \
    --network=consumer-vpc \
    --action=DENY \
    --rules=ALL \
    --direction=EGRESS \
    --priority=65534 \
    --source-ranges="192.168.10.0/28" \
    --destination-ranges="0.0.0.0/0" \
    --enable-logging

7. Erstellen Sie eine Firewallrichtlinie für das VPC-Netzwerk, um Threat Intelligence zu gewährleisten:

Im folgenden Abschnitt erstellen Sie eine Firewallrichtlinie, mit der Sie die verwalteten Bedrohungslisten von Google nutzen können, um bekannte schädliche Websites zu blockieren, bevor Traffic vom SWP empfangen wird.

Erstellen Sie in Cloud Shell die globale Firewallrichtlinie:

gcloud compute network-firewall-policies create psc-secure-policy \
    --global \
    --description="Policy to protect VPC with Threat Intelligence"

Verknüpfen Sie die Richtlinie in Cloud Shell mit Ihrer VPC:

gcloud compute network-firewall-policies associations create \
    --firewall-policy=psc-secure-policy \
    --network=consumer-vpc \
    --name=psc-swp-association \
    --global-firewall-policy

Fügen Sie in Cloud Shell die Threat Intelligence-Regeln hinzu:

Diese Regeln blockieren Traffic von bekannten böswilligen Akteuren, bevor der Traffic vom Agent initiiert wird. In diesem Beispiel haben wir Regeln zum Blockieren von Tor-Ausgangsknoten (ausgehend), zum Blockieren bekannter schädlicher IP-Adressen (ausgehend), zum Blockieren bekannter anonymer Proxys(ausgehend) und zum Blockieren von Krypto-Minern hinzugefügt, um eine unautorisierte Ressourcennutzung zu verhindern (ausgehend).

gcloud compute network-firewall-policies rules create 100 \
    --firewall-policy=psc-secure-policy \
    --action=deny \
    --direction=EGRESS \
    --dest-threat-intelligence=iplist-tor-exit-nodes \
    --layer4-configs=all \
    --enable-logging \
    --description="Block anonymous Tor traffic" \
    --global-firewall-policy
gcloud compute network-firewall-policies rules create 110 \
    --firewall-policy=psc-secure-policy \
    --action=deny \
    --direction=EGRESS \
    --dest-threat-intelligence=iplist-known-malicious-ips \
    --layer4-configs=all \
    --enable-logging \
    --description="Block known botnets and malware sources" \
    --global-firewall-policy
gcloud compute network-firewall-policies rules create 120 \
    --firewall-policy=psc-secure-policy \
    --action=deny \
    --direction=EGRESS \
    --dest-threat-intelligence=iplist-anon-proxies \
    --layer4-configs=all \
    --enable-logging \
    --description="Block Known Anonymous Proxies" \
    --global-firewall-policy
gcloud compute network-firewall-policies rules create 130 \
    --firewall-policy=psc-secure-policy \
    --action=deny \
    --direction=EGRESS \
    --dest-threat-intelligence=iplist-crypto-miners \
    --layer4-configs=all \
    --enable-logging \
    --description="Block Crypto Miners (Prevent unauthorized resource usage)" \
    --global-firewall-policy

8. Jupyter-Notebook erstellen

Im folgenden Abschnitt wird beschrieben, wie Sie ein Jupyter-Notebook erstellen. Dieses Notebook wird verwendet, um Agent Engine für einen expliziten Proxy für den Internetzugriff bereitzustellen.

Vom Nutzer verwaltetes Dienstkonto erstellen

Im folgenden Abschnitt erstellen Sie ein Dienstkonto, das der in der Anleitung verwendeten Vertex AI Workbench-Instanz zugeordnet wird.

Im Rahmen der Anleitung werden dem Dienstkonto die folgenden Rollen zugewiesen:

Erstellen Sie das Dienstkonto in Cloud Shell.

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

Aktualisieren Sie das Dienstkonto in Cloud Shell mit der Rolle „Storage-Administrator“.

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

Aktualisieren Sie das Dienstkonto in Cloud Shell mit der Rolle „Vertex AI User“.

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

Aktualisieren Sie das Dienstkonto in Cloud Shell mit der Rolle „Artifact Registry-Administrator“.

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

Erlauben Sie in Cloud Shell dem Notebook-Dienstkonto, das Compute Engine-Standarddienstkonto zu verwenden.

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"

9. Vertex AI Workbench-Instanz erstellen

Erstellen Sie im folgenden Abschnitt eine Vertex AI Workbench-Instanz, in die das zuvor erstellte Dienstkonto „notebook-sa“ eingebunden ist.

Erstellen Sie in Cloud Shell die private-client-Instanz.

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=notebook-subnet --disable-public-ip --shielded-secure-boot=true --shielded-integrity-monitoring=true --shielded-vtpm=true --service-account-email=notebook-sa@$projectid.iam.gserviceaccount.com     

Fügen Sie dem vorhandenen sicheren Web-Proxy eine weitere Regel hinzu, um den Traffic von dieser Notebook-Instanz weiterzuleiten:

Erstellen Sie in Cloud Shell die Datei „rule-notebook.yaml“ mit einem Texteditor und aktualisieren Sie die YAML-Datei mit Ihrer Projekt-ID.

cat > rule-notebook.yaml << EOF
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/my-swp-policy/rules/allow-notebook-subnet
description: Allow Internet access for notebook subnet
enabled: true
priority: 2
basicProfile: ALLOW
sessionMatcher: inIpRange(source.ip,'192.168.20.2')
EOF

Generieren Sie in Cloud Shell eine Sicherheitsrichtlinienregel:

gcloud network-security gateway-security-policies rules import allow-notebook-subnet \
    --source=rule-notebook.yaml \
    --location=us-central1 \
    --gateway-security-policy=my-swp-policy

10. Aktualisierung des Vertex AI-Dienst-Agents

Vertex AI führt in Ihrem Namen Vorgänge aus, z. B. das Abrufen einer IP-Adresse aus dem PSC Network Attachment-Subnetz, das zum Erstellen der PSC-Schnittstelle verwendet wird. Dazu verwendet Vertex AI einen Dienst-Agent (siehe unten), für den die Berechtigung Netzwerkadministrator erforderlich ist:

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

Rufen Sie in Cloud Shell Ihre Projektnummer ab.

gcloud projects describe $projectid | grep projectNumber

Legen Sie in Cloud Shell Ihre Projektnummer fest.

projectnumber=YOUR-PROJECT-NUMBER

Erstellen Sie in Cloud Shell ein Dienstkonto für AI Platform. Überspringen Sie diesen Schritt, wenn Sie bereits ein Dienstkonto in Ihrem Projekt haben.

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

Aktualisieren Sie in Cloud Shell das Dienstkonto des Dienst-Agents mit der Rolle „compute.networkAdmin“.

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

Aktualisieren Sie in Cloud Shell das Dienstkonto des Dienst-Agents mit der Rolle „dns.peer“.

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

Aktualisierung des Standarddienstkontos

Gewähren Sie Ihrem Standarddienstkonto Zugriff auf Vertex AI. Es kann einige Zeit dauern, bis die Zugriffsänderung wirksam wird.

Aktualisieren Sie in Cloud Shell das Standarddienstkonto mit der Rolle „aiplatform.user“.

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

11. Agent Engine bereitstellen

Hinweis:Für die Aufgaben in diesem Abschnitt verwenden wir die GCP Console und das JupyterLab-Notebook.

Im folgenden Abschnitt erstellen Sie ein Notebook, das die folgenden Aufgaben ausführt:

  • Verwendet die Frankfurter API (https://api.frankfurter.app/) zum Abrufen von Wechselkursdaten
  • Verweist auf einen expliziten Proxy (proxy_server), der mit dem FQDN „swp.demo.com“ auf den SWP in der VPC des Verbrauchers ausgerichtet ist.
  • dnsPeeringConfigs definieren „domain“: „demo.com.“

Führen Sie den Trainingsjob in der Vertex AI Workbench-Instanz aus.

  • Rufen Sie in der Google Cloud Console Vertex AI → Workbench auf.
  • Klicken Sie neben dem Namen der Vertex AI Workbench-Instanz (workbench-tutorial) auf „JupyterLab öffnen“. Ihre Vertex AI Workbench-Instanz öffnet JupyterLab.
  • File > New > Notebook auswählen
  • Kernel > Python 3 auswählen

Installieren Sie die erforderlichen Python-Bibliotheken: Installieren Sie die für Agent Engine erforderlichen Bibliotheken, darunter pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys und langchain-google-vertexai.

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Befehl aus. Geben Sie dabei die IP-Adresse des SWP an.

7b827a6a38bb5afc.png

!pip install --proxy http://10.10.10.5:8888 --upgrade google-cloud-aiplatform[agent_engines,adk]

Definieren Sie die folgenden Variablen basierend auf Ihrer Umgebung im folgenden Code-Snippet:

  • PROJECT_ID
  • BUCKET_NAME
  • AGENT_NAME

In diesem Lab verwenden Sie die Variablen BUCKET_NAME und AGENT_NAME, um Ihren global verfügbaren Storage-Bucket zu initialisieren und zu konfigurieren.

Im folgenden Abschnitt wird der PROXY_SERVER definiert, z. B. swp.demo.com, für den DNS-Peering für die Namensauflösung erforderlich ist. In der Konfiguration wird AGENT_PEER_DOMAIN als demo.com bereitgestellt. Das entspricht der privaten DNS-Zone, die in einem früheren Schritt im AGENT_PEER_NETWORK, consumer-vpc, erstellt wurde.

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie Folgendes aus:

# --- Fundamental Project Configuration ---
PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "us-central1" # e.g., "us-central1"
BUCKET_NAME = "YOUR_BUCKET_NAME" # A GCS bucket in the same location

# --- Agent Configuration ---
AGENT_NAME = "YOUR_AGENT_NAME"
MODEL = "gemini-2.5-flash" # Or another suitable model

# --- Network and Proxy Configuration ---
# The agent will call the Frankfurter API via this proxy
PROXY_SERVER = "http://swp.demo.com:8888"

# --- Deployment Configuration (PSC & DNS Peering) ---
# This should be a pre-existing Network Attachment
NETWORK_ATTACHMENT_NAME = f"projects/{PROJECT_ID}/regions/{LOCATION}/networkAttachments/psc-network-attachment"
# Optional DNS Peering config
AGENT_PEER_DOMAIN = "demo.com."
AGENT_PEER_NETWORK = "consumer-vpc"

# --- Initialize Vertex AI SDK ---
import vertexai
STAGING_BUCKET = f"gs://{BUCKET_NAME}"

vertexai.init(project=PROJECT_ID, location=LOCATION, staging_bucket=STAGING_BUCKET)

print(f"Vertex AI SDK initialized for project {PROJECT_ID} in {LOCATION}.")

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus.

!adk create $AGENT_NAME --model=$MODEL --project=$PROJECT_ID --region=$LOCATION

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus, um die Proxyvariable zu erstellen, die dem FQDN und Port des SWP entspricht.

import os
os.environ["PROXY_SERVER_URL"] = "http://swp.demo.com:8888"

Die folgende Codezelle zeigt die explizite Proxykonfiguration für Agent Engine, um über die Angabe des SWP mit PROXY_SERVER_TO_USE, das os.environ["PROXY_SERVER_URL"]. zuordnet, auf den Internetendpunkt api.frankfurter.app zuzugreifen.

import requests
# Use the globally defined proxy server URL
    proxies = {
       "http": PROXY_SERVER_TO_USE,
       "https": PROXY_SERVER_TO_USE,
    }
    try:
        response = requests.get(
            f"https://api.frankfurter.app/{currency_date}",
            params={"from": currency_from, "to": currency_to},
            proxies=proxies,
) 
response.raise_for_status() 
print(response.json()) 
except requests.exceptions.RequestException as e: print(f"An error occurred: {e}")

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus, der die Tool-Implementierung für die API für die Währungsumrechnung api.frankfurter.app definiert.

%%writefile $AGENT_NAME/agent.py
from google.adk.agents.llm_agent import Agent
import os
import requests


# Get Proxy Server URL
# This is the VM's FQDN to reach the proxy vm in the consumers network
if "PROXY_SERVER_URL" not in os.environ:
    raise ValueError("Missing required environment variable: PROXY_SERVER_URL is not set.")
PROXY_SERVER_TO_USE = os.environ["PROXY_SERVER_URL"]

# Mock tool implementation
def get_exchange_rate(
    currency_from: str = "USD",
    currency_to: str = "EUR",
    currency_date: str = "latest",
):
    """Retrieves the exchange rate between two currencies on a specified date.

    Uses the Frankfurter API (https://api.frankfurter.app/) to obtain
    exchange rate data.

    Args:
        currency_from: The base currency (3-letter currency code).
            Defaults to "USD" (US Dollar).
        currency_to: The target currency (3-letter currency code).
            Defaults to "EUR" (Euro).
        currency_date: The date for which to retrieve the exchange rate.
            Defaults to "latest" for the most recent exchange rate data.
            Can be specified in YYYY-MM-DD format for historical rates.

    Returns:
        dict: A dictionary containing the exchange rate information.
            Example: {"amount": 1.0, "base": "USD", "date": "2023-11-24",
                "rates": {"EUR": 0.95534}}
    """
    # Use the globally defined proxy server URL
    proxies = {
       "http": PROXY_SERVER_TO_USE,
       "https": PROXY_SERVER_TO_USE,
    }
    
    try:
        response = requests.get(
            f"https://api.frankfurter.app/{currency_date}",
            params={"from": currency_from, "to": currency_to},
            proxies=proxies,
        )
        response.raise_for_status()  # Raise an error for bad responses
        return response.json()
    except Exception as e:
        return f"An unexpected error occurred: {e}"

root_agent = Agent(
    model='gemini-2.5-flash',
    name='root_agent',
    description="Provides the currency exchange rates between two currencies",
    instruction="You are a helpful assistant that provides the currency exchange rates between two currencies. Use the 'get_exchange_rate' tool for this purpose.",
    tools=[get_exchange_rate],
)

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus.

# 1. Set your variables
CURRENCY_DATE="latest"
CURRENCY_FROM="USD"
CURRENCY_TO="EUR"
PROXY_SERVER="http://swp.demo.com:8888"

# 2. Run the curl command
!curl -x "$PROXY_SERVER" "https://api.frankfurter.app/$CURRENCY_DATE?from=$CURRENCY_FROM&to=$CURRENCY_TO"

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Befehl aus, der die von Agent Engine verwendete PSC-Schnittstellenkonfiguration zusätzlich zum DNS-Peering aufruft.

import json
import os

CONFIG_FILE_PATH = os.path.join(AGENT_NAME, ".agent_engine_config.json")
# Create your config as a Python dictionary ---
config_data = {
    "requirements": [
        "google-cloud-aiplatform[agent_engines,adk]",
        "requests",
    ],
    "psc_interface_config": {
        "network_attachment": NETWORK_ATTACHMENT_NAME,
        "dns_peering_configs": [
            {
                "domain": AGENT_PEER_DOMAIN,
                "target_project": PROJECT_ID,
                "target_network": AGENT_PEER_NETWORK,
            },
        ],
    },
}

# Write the dictionary to a JSON file ---
os.makedirs(AGENT_NAME, exist_ok=True) # Ensure the directory exists
with open(CONFIG_FILE_PATH, 'w') as f:
    json.dump(config_data, f, indent=4)

print(f"Successfully created {CONFIG_FILE_PATH} with your variables.")

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus.

import json
import os

CONFIG_FILE_PATH = os.path.join(AGENT_NAME, ".agent_engine_config.json")
# Create your config as a Python dictionary ---
config_data = {

    "psc_interface_config": {
        "network_attachment": NETWORK_ATTACHMENT_NAME,
        "dns_peering_configs": [
            {
                "domain": AGENT_PEER_DOMAIN,
                "target_project": PROJECT_ID,
                "target_network": AGENT_PEER_NETWORK,
            },
        ],
    },
}

# Write the dictionary to a JSON file ---
os.makedirs(AGENT_NAME, exist_ok=True) # Ensure the directory exists
with open(CONFIG_FILE_PATH, 'w') as f:
    json.dump(config_data, f, indent=4)

print(f"Successfully created {CONFIG_FILE_PATH} with your variables.")

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus.

%%writefile $AGENT_NAME/.env

GOOGLE_CLOUD_PROJECT=PROJECT_ID
GOOGLE_CLOUD_LOCATION=us-central1
GOOGLE_GENAI_USE_VERTEXAI=1


PROXY_SERVER_URL=http://swp.demo.com:8888

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus, um den Agent zu erstellen.

!adk deploy agent_engine $AGENT_NAME --staging_bucket=$STAGING_BUCKET --env_file=$AGENT_NAME/.env --agent_engine_config_file=$AGENT_NAME/.agent_engine_config.json --display_name=$AGENT_NAME

Beim Ausführen der Zelle wird eine ID für die Reasoning Engine generiert. Für den nächsten Schritt benötigen Sie die generierte ID, die in diesem Beispiel 3235268984265768960 ist.

✅ Created agent engine: projects/9315891080/locations/us-central1/reasoningEngines/3235268984265768960

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus. Achten Sie darauf, dass Sie Ihre Projektnummer und die Reasoning-ID der Agent Engine aus der vorherigen Ausgabe aktualisieren:

from vertexai import agent_engines
remote_app = agent_engines.get("projects/PROJECT_NUMBER/locations/us-central1/reasoningEngines/ENTER_YOUR_ID")

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus.

def print_event_nicely_with_thoughts(event):
    """
    Parses and prints streaming query events, including thoughts.
    """
    try:
        content = event.get('content', {})
        role = content.get('role')
        parts = content.get('parts', [{}])

        if not parts:
            print("...")
            return

        part = parts[0] # Get the first part

        # Event 1: Model is thinking (calling a tool or just text)
        if role == 'model':

            # Check for and print any explicit 'thought' text
            if 'thought' in part:
                print(f"🧠 Thought: {part['thought']}")

            # Check for a function call
            if 'function_call' in part:
                # If we haven't *already* printed an explicit thought,
                # print a generic one.
                if 'thought' not in part:
                    print("🧠 Thinking... (decided to use a tool)")

                call = part['function_call']
                print(f"   🔧 Tool Call: {call.get('name')}()")
                print(f"      Args: {call.get('args')}")

            # Check for the final text answer
            elif 'text' in part:
                text = part.get('text', '')
                print(f"\n💬 Model: {text}")

        # Event 2: The tool returns its result
        elif role == 'user' and 'function_response' in part:
            resp = part['function_response']
            print(f"⚙️ Tool Response (from {resp.get('name')}):")
            print(f"   Output: {resp.get('response')}")

        # Other event types (like progress messages)
        else:
            print("...") # Show progress for other events

    except Exception as e:
        print(f"Error processing event: {e}")
        # print(f"Raw event: {event}") # Uncomment to debug



for event in remote_app.stream_query(
    user_id="u_456",
    # session_id=remote_session["id"],
    message="Provide USD to INR conversion rate",
):
    print_event_nicely_with_thoughts(event)

Beispiel für eine erfolgreiche Ausführung, die die Verbindung zum öffentlichen Endpunkt api.frankfurther.app über den SWP auf Grundlage des Umrechnungskurses von USD in INR validiert.

f9f925983ab5cc9d.png

12. PSC-Schnittstellenvalidierung

Sie können die von Agent Engine verwendeten Network Attachment-IPs auch so aufrufen:

„Network Services“ → „Private Service Connect“ → „Network Attachment“ → „psc-network-attachment“

Wählen Sie das Mandantenprojekt aus (Projektname endet auf „-tp“).

c9c412334a7f5ad9.png

Das hervorgehobene Feld gibt die IP-Adresse an, die von Agent Engine über den PSC-Netzwerkanhang verwendet wird.

e94c6c03fb51f7fe.png

13. SWP – Cloud Logging-Validierung

Sie können Cloud Logging aufrufen, um den vom SWP ausgeführten Internet-Egress zu prüfen. Gehen Sie dazu so vor:

„Monitoring“ → „Log-Explorer“

Fügen Sie die Abfrage ein: resource.type=" networkservices.googleapis.com/Gateway". Klicken Sie dann auf „Abfrage ausführen“. Im Folgenden sehen Sie ein Beispiel, in dem der Zielendpunkt api.frankfurter.app bestätigt wird.

f53831ef8ec663db.png

fc154a5b22da2a87.png

Im folgenden Cloud Logging-Beispiel wird Folgendes validiert:

Destination_range: Agent Engine PSC Interface IP Address (Zielbereich: IP-Adresse der Agent Engine-PSC-Schnittstelle)

Source_range: Nur-Proxy-Subnetz Dest_ip: IP-Adresse des sicheren Web-Proxys

Achten Sie darauf, dass Sie die project_id für die Cloud-Logging-Abfrage ändern.

logName:("projects/project_id/logs/compute.googleapis.com%2Ffirewall") AND jsonPayload.rule_details.reference:("network:consumer-vpc/firewall:allow-access-to-swp")
{
  "insertId": "1j9ym95fmu8g6o",
  "jsonPayload": {
    "vpc": {
      "project_id": "XXXXXXXXXXXXX",
      "subnetwork_name": "intf-subnet",
      "vpc_name": "consumer-vpc"
    },
    "rule_details": {
      "destination_range": [
        "10.10.10.5/32"
      ],
      "reference": "network:consumer-vpc/firewall:allow-access-to-swp",
      "priority": 1000,
      "source_range": [
        "192.168.10.0/28"
      ],
      "direction": "EGRESS",
      "ip_port_info": [
        {
          "ip_protocol": "ALL"
        }
      ],
      "action": "ALLOW"
    },
    "disposition": "ALLOWED",
    "remote_instance": {
      "region": "us-central1"
    },
    "remote_vpc": {
      "vpc_name": "consumer-vpc",
      "project_id": "XXXXXXXXXXXXXXX",
      "subnetwork_name": "swp-subnet"
    },
    "connection": {
      "src_ip": "192.168.10.2",
      "src_port": 48640,
      "dest_port": 8888,
      "dest_ip": "10.10.10.5",
      "protocol": 6
    }
  },
  "resource": {
    "type": "gce_subnetwork",
    "labels": {
      "subnetwork_id": "7147084067647653041",
      "project_id": "XXXXXXXXXXXXXX",
      "location": "us-central1",
      "subnetwork_name": "intf-subnet"
    }
  },
  "timestamp": "2025-12-30T12:51:36.628538815Z",
  "logName": "projects/dec30-run1-agent/logs/compute.googleapis.com%2Ffirewall",
  "receiveTimestamp": "2025-12-30T12:51:40.846652708Z"
}

14. Bereinigen

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus, um das Löschen der Agent Engine-Bereitstellung auszulösen.

Achten Sie darauf, dass Sie "project number" und "reasoningEngines token" aktualisieren.

import requests
token = !gcloud auth application-default print-access-token
ENDPOINT = "https://us-central1-aiplatform.googleapis.com"
response = requests.delete(
    f"{ENDPOINT}/v1beta1/projects/218166745590/locations/us-central1/reasoningEngines/3086854705725308928",
    params={"force": "true"},
    headers={
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {token[0]}"
    },
)
print(response.text)

Löschen Sie die Komponenten der Anleitung in Cloud Shell.

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

gcloud network-security gateway-security-policies rules delete allow-notebook-subnet \
    --gateway-security-policy=my-swp-policy \
    --location=us-central1

gcloud network-security gateway-security-policies rules delete allow-example \
    --gateway-security-policy=my-swp-policy \
    --location=us-central1

gcloud network-security gateway-security-policies delete my-swp-policy \
    --location=us-central1
gcloud network-services gateways delete my-swp-instance\
    --location=us-central1

gcloud dns record-sets delete swp.demo.com --zone=private-dns-codelab  --type=A

gcloud dns managed-zones delete private-dns-codelab


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

export ROUTER_NAME=$(gcloud compute routers list --regions=us-central1 \
    --filter="name ~ swg-autogen-router" --format="value(name)")


 gcloud compute routers nats delete swg-autogen-nat --router=$ROUTER_NAME --region=us-central1 --quiet 

gcloud compute routers delete $ROUTER_NAME --region=us-central1 --quiet

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

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

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

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

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

gcloud compute networks delete consumer-vpc --quiet

15. Glückwunsch

Sie haben Agent Engine erfolgreich konfiguriert und validiert, die mit einer Private Service Connect-Schnittstelle bereitgestellt wird und bei der der ausgehende Internet-Traffic über einen expliziten Proxy erfolgt.

Sie haben die Infrastruktur des Nutzers erstellt und einen Netzwerkanhang hinzugefügt, der es dem Produzenten ermöglicht, eine VM mit mehreren NICs zu erstellen, um die Kommunikation zwischen Nutzer und Produzent zu ermöglichen. Sie haben gelernt, wie Sie ein explizites Proxy- und DNS-Peering erstellen, das eine Internetverbindung ermöglicht.

Cosmopup findet Tutorials toll!!

e6d3675ca7c6911f.jpeg

Nächste Schritte

Weitere Informationen und Videos

Referenzdokumente