Agent Engine PSC Explicit Proxy

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 On-Premise-Ziele innerhalb des RFC1918-Adressblocks weiterleiten.
  • Für PSC-Schnittstellen, die auf Adressblöcke außerhalb von RFC 1918 ausgerichtet sind, ist ein expliziter Proxy erforderlich, der in der VPC des Nutzers mit einer RFC 1918-Adresse bereitgestellt wird. Innerhalb der Vertex AI-Bereitstellung muss der Proxy zusammen mit einem FQDN des Zielendpunkts definiert werden.
  • Wenn Sie Ihre Bereitstellung nur mit einer PSC-Schnittstelle konfigurieren, behält sie ihren Standard-Internetzugriff bei. Dieser ausgehende Traffic wird direkt aus dem sicheren, von Google verwalteten Mandantennetzwerk weitergeleitet.

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

  • Wenn Ihr Projekt Teil eines VPC Service Controls-Perimeters ist, wird der standardmäßige Internetzugriff der von Google verwalteten Mandanten durch den Perimeter blockiert, um Daten-Exfiltration zu verhindern.
  • Damit die Bereitstellung in diesem Szenario auf das öffentliche Internet zugreifen kann, müssen Sie explizit einen sicheren Pfad für ausgehenden Traffic konfigurieren, der Traffic über Ihre VPC weiterleitet.
  • Die empfohlene Methode hierfür ist, einen Proxyserver mit einer RFC1918-Adresse in Ihrem VPC-Perimeter einzurichten und ein Cloud NAT-Gateway zu erstellen, damit die Proxy-VM auf das Internet zugreifen kann.

Weitere Informationen finden Sie in den folgenden Ressourcen:

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 wird, um die Verbindung zu einer öffentlichen Website (https://api.frankfurter.app/) über eine Proxy-VM zu ermöglichen, die in der VPC des Nutzers mit einer RFC1918-Adresse bereitgestellt wird. Die Beispielbereitstellung ist in einem VPC-SC-aktivierten Projekt oder für Administratoren anwendbar, die Internet-Egress über das Netzwerk des Kunden anstelle der Mandanten-VPC benötigen.

Abbildung 1

f42f2db921f6d5af.png

Sie erstellen eine einzelne psc-network-attachment in der VPC des Nutzers und nutzen DNS-Peering, um die Proxy-VM des Nutzernetzwerks im Mandantenprojekt aufzulösen, in dem Agent Engine gehostet wird. Dies führt zu den folgenden Anwendungsfällen:

Agent Engine bereitstellen und eine Proxy-VM als expliziten Proxy konfigurieren, damit sie die öffentliche URL „https://api.frankfurter.app“ erreichen kann

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
  • Proxy-VM für ausgehenden Internet-Traffic bereitstellen und verwenden

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 list project
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"

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
  • Cloud Router (erforderlich für Cloud NAT)
  • Cloud NAT

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 die Proxy-VM:

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

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

Cloud Router- und NAT-Konfiguration

In dieser Anleitung wird Cloud NAT verwendet, um der Proxy-VM, die keine öffentliche IP-Adresse hat, Internetzugriff zu ermöglichen. Cloud NAT ermöglicht es VMs mit nur privaten IP-Adressen, eine Verbindung zum Internet herzustellen, sodass sie Aufgaben wie das Installieren von Softwarepaketen ausführen können.

Erstellen Sie den Cloud Router in Cloud Shell.

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

Erstellen Sie in Cloud Shell das NAT-Gateway mit aktiviertem Logging. Wir verwenden die Protokollierung, um den Zugriff auf die öffentliche IP-Adresse für die Frankfurter API (https://api.frankfurter.app/) zu validieren.

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. IAP aktivieren

Damit IAP eine Verbindung zu Ihren VM-Instanzen herstellen kann, erstellen Sie eine Firewallregel, die:

  • Gilt für alle VM-Instanzen, die über IAP zugänglich sein sollen.
  • Lässt eingehenden Traffic aus dem IP-Bereich 35.235.240.0/20 zu. Dieser Bereich enthält alle IP-Adressen, die IAP für die TCP-Weiterleitung verwendet.

Erstellen Sie in Cloud Shell die IAP-Firewallregel.

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

5. Consumer-VM-Instanzen erstellen

Erstellen Sie in Cloud Shell die Nutzer-VM-Instanz „proxy-vm“, die als expliziter Proxy für Agent Engine dient. Wir verwenden tinyproxy als Anwendung zum Weiterleiten von HTTP-Traffic.

gcloud compute instances create proxy-vm \
    --project=$projectid \
    --machine-type=e2-micro \
    --image-family debian-11 \
    --no-address \
    --can-ip-forward \
    --image-project debian-cloud \
    --zone us-central1-a \
    --subnet=rfc1918-subnet1 \
    --shielded-secure-boot \
    --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. 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“

8eec51cb197da218.png

7. 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 Proxy-VM verweist. Später wird DNS-Peering in Agent Engine bereitgestellt, wodurch der Zugriff auf die DNS-Einträge des Nutzers ermöglicht 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 der Instanzen ab, die für DNS-A-Einträge verwendet werden, und speichern Sie sie.

Führen Sie in Cloud Shell einen „describe“-Befehl für die VM-Instanzen aus.

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

Erstellen Sie in Cloud Shell den Datensatz für die VM „proxy-vm.demo.com“. Achten Sie darauf, die IP-Adresse entsprechend der Ausgabe Ihrer Umgebung zu aktualisieren.

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

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

Erstellen Sie im folgenden Abschnitt eine Firewallregel, die Traffic, der vom PSC-Netzwerkanhang stammt, den Zugriff auf die Proxy-VM in der Consumer-VPC ermöglicht.

Erstellen Sie in Cloud Shell die Firewallregel für eingehenden Traffic.

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

8. Jupyter-Notebook erstellen

Im folgenden Abschnitt wird beschrieben, wie Sie ein Jupyter-Notebook erstellen. Dieses Notebook wird verwendet, um Agent Engine mit einem 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. Expliziten Proxy aktualisieren

Im folgenden Abschnitt müssen Sie eine SSH-Verbindung zum expliziten Proxy herstellen, die Konfigurationsdatei „tinyproxy.conf“ aktualisieren und dann einen Reset durchführen.

Über Cloud Shell

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

Öffnen Sie die Tinyproxy-Konfigurationsdatei und aktualisieren Sie sie mit einem Editor Ihrer Wahl. Unten sehen Sie ein Beispiel mit 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

10. 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=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. 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"

12. Tcpdump der Proxy-VM

Um die IP-Verbindung von der Agent Engine aus zu validieren, können wir TCPDUMP verwenden. So können wir die Kommunikation beobachten, die vom PSC Network Attachment-Subnetz 192.168.10.0/28 ausgeht, wenn die GET-Anfrage von Agent Engine an die öffentliche URL gesendet wird.

Stellen Sie in Cloud Shell über SSH eine Verbindung zur Proxy-VM her.

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

Führen Sie „tcpdump“ im Betriebssystem der Proxy-VM aus.

sudo tcpdump -i any net 192.168.10.0/28 -nn

13. Agent Engine bereitstellen

Hinweis:Für die Aufgaben in diesem Abschnitt verwenden wir die GCP Console und ein 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 „proxy-vm.demo.com“ auf die Proxy-VM in der VPC des Kunden 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.
  • Wählen Sie „Datei“ > „Neu“ > „Notebook“ aus.
  • Wählen Sie „Kernel“ > „Python 3“ aus.

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 Code aus.

!pip install pyyaml
!pip install google-cloud-aiplatform[agent_engines,langchain]==1.96.0
!pip install cloudpickle==3.1.1
!pip install google-cloud-api-keys
!pip install langchain-google-vertexai==2.0.24

Jupyter Notebook-Kernel neu starten: So wird sichergestellt, dass neu installierte Bibliotheken korrekt geladen werden.

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

# Restart the notebook kernel after install, so you can run langchain successfully.

import IPython

app = IPython.Application.instance()
app.kernel.do_shutdown(True)

Projekt- und Bucket-Variablen festlegen: Definieren Sie Ihre Google Cloud-Projekt-ID, Projektnummer, Dienstname, GCS-Verzeichnis, Endpunkt, Bucket-Name und ‑Standort.

Aktualisieren Sie die folgenden Felder, bevor Sie die Zelle ausführen.

  • PROJECT_ID = "enter-your-projectid"
  • PROJECT_NUMBER = "enter-your-projectnumber"
  • BUCKET= "enter-a-unique-bucket-name"

Hinweis: Wir verwenden die Variable BUCKET, um im nächsten Schritt einen Cloud Storage-Bucket zu erstellen.

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

PROJECT_ID = "enter-your-projectid"  #@param {type:"string"}
PROJECT_NUMBER = "enter-your-projectnumber"  #@param {type:"string"}
SERVICE_NAME = "aiplatform"  #@param ["autopush-aiplatform", "staging-aiplatform", "aiplatform"]
# @markdown  Specify where your agent code should be written in GCS:
GCS_DIR = "reasoning-engine-test"  #@param {type:"string"}
ENDPOINT = "https://us-central1-aiplatform.googleapis.com" # @param ["https://us-central1-aiplatform.googleapis.com", "https://us-central1-autopush-aiplatform.sandbox.googleapis.com", "https://us-central1-staging-aiplatform.sandbox.googleapis.com"]
BUCKET= "enter-a-unique-bucket-name" #@param {type:"string"}
LOCATION="us-central1" #@param {type:"string"}

GCS-Bucket erstellen: Erstellen Sie einen Cloud Storage-Bucket zum Speichern von Agent-Code.

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

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

Name des Netzwerkanhangs definieren: Geben Sie den Namen Ihres Private Service Connect-Netzwerkanhangs an.

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

NETWORK_ATTACHMENT_NAME = 'psc-network-attachment' #@param {type:"string"}

Python-Clientbibliotheken initialisieren: Richten Sie die erforderlichen Clientbibliotheken für Google Cloud-Dienste ein.

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

import json
import pprint

import cloudpickle
from google import auth as google_auth
from google.auth.transport import requests as google_requests
from google.cloud import storage
import yaml


def get_identity_token():
    """Gets ID token for calling Cloud Run."""
    credentials, _ = google_auth.default()
    auth_request = google_requests.Request()
    credentials.refresh(auth_request)
    return credentials.id_token

if not GCS_DIR or "your_ldap" in GCS_DIR:
    raise ValueError("GCS_DIR must be set or you must set your ldap.")

if not PROJECT_ID:
    raise ValueError("PROJECT_ID must be set.")


client = storage.Client(project=PROJECT_ID)
bucket = client.get_bucket(BUCKET)

Agent und Tools konfigurieren: Definieren Sie die StreamingAgent-Klasse und die get_exchange_rate-Funktion, um Währungskurse über die Frankfurter API über den expliziten Proxy abzurufen.

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie die folgende Konfiguration aus. Beachten Sie dabei die folgenden Punkte:

  • Die Funktion „get_exchange_rate“ verwendet die Frankfurter API (https://api.frankfurter.app/), um die Wechselkursdaten abzurufen.
  • proxy_server = "http://proxy-vm.demo.com:8888" Der FQDN ist der Proxy-VM zugeordnet, die im Nutzer-VPC bereitgestellt wird. Wir verwenden DNS-Peering, um den FQDN in einem späteren Schritt aufzulösen.
from langchain_google_vertexai import ChatVertexAI
from langchain.agents import AgentExecutor
from langchain.agents.format_scratchpad.tools import format_to_tool_messages
from langchain.agents.output_parsers.tools import ToolsAgentOutputParser
from langchain.tools.base import StructuredTool
from langchain_core import prompts
from re import S
from typing import Callable, Sequence
import google.auth
import vertexai


class StreamingAgent:

    def __init__(
            self,
            model: str,
            tools: Sequence[Callable],
            project_id: str,
        ):
        self.model_name = model
        self.tools = tools
        self.project_id = project_id

    def set_up(self):
        """All unpickle-able logic should go here.

        The .set_up() method should not be called for an object that is being
        prepared for deployment.
        """
        creds, _ = google.auth.default(quota_project_id=self.project_id)
        vertexai.init(project=self.project_id, location="us-central1", credentials=creds)

        prompt = {
            "input": lambda x: x["input"],
            "agent_scratchpad": (
                lambda x: format_to_tool_messages(x["intermediate_steps"])
            ),
        } | prompts.ChatPromptTemplate.from_messages([
            ("user", "{input}"),
            prompts.MessagesPlaceholder(variable_name="agent_scratchpad"),
        ])

        llm = ChatVertexAI(model_name=self.model_name)
        if self.tools:
            llm = llm.bind_tools(tools=self.tools)

        self.agent_executor = AgentExecutor(
            agent=prompt | llm | ToolsAgentOutputParser(),
            tools=[StructuredTool.from_function(tool) for tool in self.tools],
        )

    def query(self, input: str):
        """Query the application.

        Args:
            input: The user prompt.

        Returns:
            The output of querying the application with the given input.
        """
        return self.agent_executor.invoke(input={"input": input})

    def stream_query(self, input: str):
        """Query the application and stream the output.

        Args:
            input: The user prompt.

        Yields:
            Chunks of the response as they become available.
        """
        for chunk in self.agent_executor.stream(input={"input": input}):
            yield chunk

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}}
    """
    import requests

    proxy_server = "http://proxy-vm.demo.com:8888" # This is the VM's FQDN to reach the proxy vm in the consumers network

    proxies = {
       "http": proxy_server,
       "https": proxy_server,
    }
    response = requests.get(
        f"https://api.frankfurter.app/{currency_date}",
        params={"from": currency_from, "to": currency_to},
        proxies=proxies,
    )
    return response.json()

Agent-Dateien in Cloud Storage hochladen: Laden Sie den serialisierten Agent und seine Anforderungen in den dafür vorgesehenen GCS-Bucket hoch.

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

# Upload files to Cloud Storage.
if not GCS_DIR:
    raise ValueError("GCS_DIR must be set.")

FILE = "streaming_agent.pkl"
blob = bucket.blob(f"{GCS_DIR}/{FILE}")
with blob.open("wb") as f:
    cloudpickle.dump(
        StreamingAgent(
            model="gemini-2.0-flash-001",  # Required.
            tools=[get_exchange_rate],  # Optional.
            project_id=PROJECT_ID
        ), f)


requirements = """
google-cloud-aiplatform[agent_engines,langchain]==1.96.0
cloudpickle==3.1.1
"""

blob = bucket.blob(f"{GCS_DIR}/requirements-streaming.txt")
blob.upload_from_string(requirements)

!gsutil ls gs://{BUCKET}/{GCS_DIR}

Agent Engine bereitstellen: Stellen Sie die Agent Engine bereit und konfigurieren Sie sie mit der PSC-Schnittstelle und dem DNS-Peering, um den FQDN der Proxy-VM in der VPC des Nutzers aufzulösen.

Erstellen und führen Sie in Ihrem JupyterLab-Notebook die folgende Zelle aus. Beachten Sie dabei die folgenden Punkte:

  • DNS-Peering für VPCs von Nutzern wird mit dnsPeeringConfigs für den Domainnamen demo.com konfiguriert.
import requests


token = !gcloud auth application-default print-access-token

response = requests.post(
    f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/{LOCATION}/reasoningEngines",
    headers={
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {token[0]}"
    },
    data=json.dumps({
        "displayName": "PSC-I Explicit Proxy",
        "description": "test psc-i agent + proxy vm",
        "spec": {
            "packageSpec": {
                "pickleObjectGcsUri": f"gs://{BUCKET}/{GCS_DIR}/streaming_agent.pkl",
                "requirementsGcsUri": f"gs://{BUCKET}/{GCS_DIR}/requirements-streaming.txt",
                "pythonVersion": "3.10"
            },
            "deploymentSpec": {
                "pscInterfaceConfig": {
                    "networkAttachment": NETWORK_ATTACHMENT_NAME,
                    "dnsPeeringConfigs": [
                    {
                      "domain": "demo.com.",
                      "targetProject": PROJECT_ID,
                      "targetNetwork": "consumer-vpc", #Consumer VPC
                    },
                  ],
                }
            }
        },
    })
)

pprint.pprint(json.loads(response.content))
reasoning_engine_id = json.loads(response.content)["name"].split("/")[5]
pprint.pprint(reasoning_engine_id)

Bereitstellungsstatus überwachen: Prüfen Sie den Status des Bereitstellungsvorgangs für die Agent Engine.

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

operation_id = json.loads(response.content)["name"].split("/")[7]
pprint.pprint(operation_id)

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

Hinweis: Dieser Vorgang kann etwa 5 Minuten dauern. Führen Sie die Zelle noch einmal aus, um den Fortschritt zu prüfen. Fahren Sie erst mit dem nächsten Abschnitt fort, wenn Sie eine Ausgabe wie im Screenshot unten sehen.

# You can run this multiple times to check the status of the deployment operation, operation takes approx 5 min.
token = !gcloud auth application-default print-access-token
response = requests.get(
    f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/{LOCATION}/operations/{operation_id}        ",
    headers={
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {token[0]}"
    }
)
pprint.pprint(json.loads(response.content))

Beispiel für einen erfolgreichen Lauf:

3f6dcd1074af7651.png

Bereitgestellten Agent abfragen: Senden Sie eine Anfrage an die bereitgestellte Agent Engine, um ihre Funktionalität zu testen.

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

response = requests.post(
    f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/{LOCATION}/reasoningEngines/{reasoning_engine_id}:query",
    headers={
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {token[0]}"
    },
    data=json.dumps({ "input": {"input": "What is the exchange rate from US dollars to Euro?"} })
)
print(response.text)

Abfrageergebnisse streamen: Streamen Sie die Ausgabe der Agent Engine-Abfrage.

Erstellen Sie in Ihrem JupyterLab-Notebook eine neue Zelle und führen Sie den folgenden Code aus, um den API-Aufruf an die öffentliche URL über den expliziten Proxy in der VPC des Nutzers auszulösen.

token = !gcloud auth application-default print-access-token
print(f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/us-central1/reasoningEngines/{reasoning_engine_id}:streamQuery")

response = requests.post(
    f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/us-central1/reasoningEngines/{reasoning_engine_id}:streamQuery",
    headers={
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {token[0]}"
    },
    data=json.dumps({ "input": {"input": "What is the exchange rate from US dollars to Euro?"} })
)
for chunk in response.iter_lines():
    print(chunk.decode('utf-8'))
# pprint.pprint(json.loads(response.content))

Beispiel für einen erfolgreichen Lauf:

1bd81d12426a348f.png

14. Tcpdump-Validierung

Sehen Sie sich die tcpdump-Ausgabe an, in der die Kommunikation zwischen der IP-Adresse für die PSC-Netzwerkverbindung, die von Agent Engine verwendet wird, und der Prox-VM nach dem POST-Vorgang der Anfrage beschrieben wird.

user@proxy-vm:~$ sudo tcpdump -i any net 192.168.10.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
22:17:53.983212 ens4  In  IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [S], seq 3841740961, win 28800, options [mss 1440,sackOK,TS val 4245243253 ecr 0,nop,wscale 7], length 0
22:17:53.983252 ens4  Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [S.], seq 2232973833, ack 3841740962, win 64768, options [mss 1420,sackOK,TS val 2251247643 ecr 4245243253,nop,wscale 7], length 0
22:17:53.985167 ens4  In  IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [.], ack 1, win 225, options [nop,nop,TS val 4245243256 ecr 2251247643], length 0
22:17:53.986476 ens4  In  IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [P.], seq 1:45, ack 1, win 16384, options [nop,nop,TS val 4245243256 ecr 2251247643], length 44
22:17:53.986485 ens4  Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [.], ack 45, win 506, options [nop,nop,TS val 2251247646 ecr 4245243256], length 0
22:17:54.043347 ens4  Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [P.], seq 1:71, ack 45, win 506, options [nop,nop,TS val 2251247703 ecr 4245243256], length 70

15. 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“).

8a4b5a6e5dfd63d7.png

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

c618359f6eafc0c6.png

16. Cloud Logging-Validierung

Beenden Sie die TCPDump-Sitzung der Proxy-VM und führen Sie einen PING an api.frankfurter.app aus, um die zugehörige öffentliche IP-Adresse zu erhalten.

ping -c4 api.frankfurter.app 

Im Beispiel wird 104.26.1.198 als öffentliche IP-Adresse für api.frankfurter.app angegeben.

user@proxy-vm:~$ ping -c4 api.frankfurter.app

PING api.frankfurter.app (104.26.1.198) 56(84) bytes of data.

64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=1 ttl=61 time=10.9 ms

64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=2 ttl=61 time=10.9 ms

64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=3 ttl=61 time=10.9 ms

64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=4 ttl=61 time=10.9 ms

Sehen wir uns das NAT-Logging an, um zu prüfen, ob Traffic für 104.26.1.198 beobachtet wird.

Rufen Sie Folgendes auf:

„Monitoring“ → „Log-Explorer“

Verwenden Sie den folgenden Filter:

resource.type="nat_gateway"

31024dc29c39084.png

Wählen Sie den Zeitraum aus und klicken Sie dann auf „Abfrage ausführen“.

5976857e92d149d3.png

Maximieren Sie den Logeintrag, in dem die öffentliche IP-Adresse (Ziel) (104.26.1.198) von api.frankfurter.app sowie die Quell-IP-Adresse und der Name der Proxy-VM angegeben sind, die die Verwendung des expliziten Proxys für den Internet-Ausgang validiert.

14e293a7fea68db4.png

17. 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.

token = !gcloud auth application-default print-access-token

response = requests.delete(
    f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/us-central1/reasoningEngines/{reasoning_engine_id}",
    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 dns record-sets delete proxy-vm.demo.com --zone=private-dns-codelab  --type=A

gcloud dns managed-zones delete private-dns-codelab

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 compute networks delete consumer-vpc --quiet

18. Glückwunsch

Sie haben die mit einer Private Service Connect-Schnittstelle bereitgestellte Agent Engine erfolgreich konfiguriert und validiert. Der ausgehende Internet-Traffic erfolgt über einen expliziten Proxy.

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!!

c911c127bffdee57.jpeg

Nächste Schritte

Weitere Informationen und Videos

Referenzdokumente