1. Введение
Интерфейс Private Service Connect — это ресурс, позволяющий сети виртуального частного облака (VPC) производителя инициировать соединения с различными пунктами назначения в сети VPC потребителя. Сети производителя и потребителя могут находиться в разных проектах и организациях.
Если сетевое подключение принимает соединение через интерфейс Private Service Connect, Google Cloud выделяет интерфейсу IP-адрес из подсети потребителя, указанной сетевым подключением. Сети потребителя и поставщика соединены и могут взаимодействовать друг с другом, используя внутренние IP-адреса.
Соединение между сетевым подключением и интерфейсом Private Service Connect похоже на соединение между конечной точкой Private Service Connect и подключением к службе, но имеет два ключевых отличия:
- Сетевое присоединение позволяет сети-производителю инициировать соединения с сетью-потребителем (управляемый выход сервиса), в то время как конечная точка позволяет сети-потребителю инициировать соединения с сетью-производителем (управляемый вход сервиса).
- Интерфейсное соединение Private Service Connect является транзитным. Это означает, что сеть-производитель может взаимодействовать с другими сетями, подключенными к сети-потребителю.
Вопросы достижимости интерфейса Vertex AI PSC
- Интерфейс PSC способен маршрутизировать трафик в VPC или локальные пункты назначения в пределах блока адресов RFC1918.
- Для интерфейса PSC, ориентированного на блоки адресов, не соответствующие стандарту RFC-1918, требуется явный прокси-сервер, развернутый в VPC потребителя с адресом RFC-1918. В рамках развертывания Vertex AI прокси-сервер должен быть определен вместе с полным доменным именем целевой конечной точки.
- При настройке развертывания только с интерфейсом PSC сохраняется доступ к Интернету по умолчанию. Исходящий трафик отправляется непосредственно из безопасной сети арендаторов, управляемой Google.
Соображения относительно VPC-SC интерфейса Vertex AI PSC
- Если ваш проект является частью периметра VPC Service Controls, доступ к Интернету по умолчанию для арендаторов, управляемых Google, блокируется периметром, чтобы предотвратить утечку данных.
- Чтобы разрешить развертыванию доступ к публичному Интернету в этом сценарии, необходимо явно настроить безопасный выходной путь, который направляет трафик через ваше VPC.
- Рекомендуемый способ добиться этого — настроить прокси-сервер внутри периметра VPC с адресом RFC1918 и создать шлюз Cloud NAT, чтобы разрешить виртуальной машине-прокси доступ к Интернету.
Дополнительную информацию можно найти на следующих ресурсах:
Развертывание агента | Генеративный ИИ на Vertex AI | Google Cloud
Настройка интерфейса Private Service Connect для ресурсов Vertex AI | Google Cloud
Что вы построите
В этом руководстве вы создадите комплексный Agent Engine, развёрнутый с интерфейсом Private Service Connect (PSC), для подключения к публичному сайту (https://api.frankfurter.app/) через виртуальную машину Proxy, развёрнутую в VPC потребителя с адресом RFC1918. Пример развёртывания применим в проектах с поддержкой VPC-SC или для администраторов, которым требуется выход в Интернет через сеть клиента, а не через VPC арендатора.
Рисунок 1
Вы создадите один psc-network-attachment в потребительском VPC, используя пиринг DNS для разрешения proxy-vm потребительской сети в проекте арендатора, на котором размещен Agent Engine. В результате будут реализованы следующие варианты использования:
Развертывание Agent Engine и настройка прокси-VM для работы в качестве явного прокси-сервера, что позволяет ему обращаться к публичному URL-адресу https://api.frankfurter.app
Чему вы научитесь
- Как создать сетевое присоединение
- Как производитель может использовать сетевое подключение для создания интерфейса PSC
- Как установить связь от производителя к потребителю с помощью DNS-пиринга
- Как развернуть и использовать прокси-виртуальную машину для выхода в Интернет
Что вам понадобится
Проект Google Cloud
Разрешения IAM
- Администратор вычислительной сети (roles/compute.networkAdmin)
- Администратор экземпляра вычислений (roles/compute.instanceAdmin)
- Администратор безопасности вычислений (roles/compute.securityAdmin)
- Администратор DNS (roles/dns.admin)
- Пользователь туннеля, защищенного IAP (roles/iap.tunnelResourceAccessor)
- Администратор журнала (roles/logging.admin)
- Администратор блокнотов (roles/notebooks.admin)
- Администратор IAM проекта (roles/resourcemanager.projectIamAdmin)
- Администратор учетной записи службы (roles/iam.serviceAccountAdmin)
- Администратор использования услуг (roles/serviceusage.serviceUsageAdmin)
2. Прежде чем начать
Обновите проект для поддержки руководства.
В этом руководстве используются $переменные для упрощения реализации конфигурации gcloud в Cloud Shell.
Внутри Cloud Shell выполните следующие действия:
gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid
Включение API
Внутри Cloud Shell выполните следующие действия:
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"
Убедитесь, что API успешно включены.
gcloud services list --enabled
3. Потребительская настройка
Создайте потребительскую VPC
Эта VPC находится в проекте клиента. В этой VPC будут созданы следующие ресурсы:
- Потребительская подсеть
- Подсеть сетевого подключения
- Облачный маршрутизатор (требуется для Cloud NAT)
- Облачный NAT
Внутри Cloud Shell выполните следующие действия:
gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom
Создайте потребительские подсети
Внутри Cloud Shell создайте подсеть для Proxy VM:
gcloud compute networks subnets create rfc1918-subnet1 --project=$projectid --range=10.10.10.0/28 --network=consumer-vpc --region=us-central1
Создайте подсеть присоединения к сети Private Service Connect
Внутри Cloud Shell создайте подсеть для сетевого подключения PSC:
gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1
Конфигурация облачного маршрутизатора и NAT
В этом руководстве Cloud NAT используется для предоставления доступа в Интернет прокси-виртуальной машине, у которой нет публичного IP-адреса. Cloud NAT позволяет виртуальным машинам, имеющим только частные IP-адреса, подключаться к Интернету, что позволяет им выполнять такие задачи, как установка пакетов программного обеспечения.
Внутри Cloud Shell создайте Cloud Router.
gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1
В Cloud Shell создайте шлюз NAT с включённым логированием. Мы будем использовать логирование для проверки доступа к публичному IP-адресу для Frankfurter API (https://api.frankfurter.app/).
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
Чтобы разрешить IAP подключаться к экземплярам ваших виртуальных машин, создайте правило брандмауэра, которое:
- Применяется ко всем экземплярам виртуальных машин, к которым вы хотите обеспечить доступ с помощью IAP.
- Разрешает входящий трафик из диапазона IP-адресов 35.235.240.0/20. Этот диапазон содержит все IP-адреса, которые IAP использует для пересылки TCP.
Внутри Cloud Shell создайте правило брандмауэра IAP.
gcloud compute firewall-rules create ssh-iap-consumer \
--network consumer-vpc \
--allow tcp:22 \
--source-ranges=35.235.240.0/20
5. Создайте экземпляры виртуальных машин потребителя
В Cloud Shell создайте экземпляр виртуальной машины-потребителя proxy-vm, который будет служить явным прокси-сервером для Agent Engine. Для проксирования HTTP-трафика мы будем использовать tinyproxy.
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
Сетевые подключения — это региональные ресурсы, представляющие сторону потребителя интерфейса Private Service Connect. Вы связываете одну подсеть с сетевым подключением, а поставщик назначает IP-адреса интерфейсу Private Service Connect из этой подсети. Подсеть должна находиться в том же регионе, что и сетевое подключение. Сетевое подключение должно находиться в том же регионе, что и служба поставщика.
Создайте сетевое присоединение
Внутри Cloud Shell создайте сетевое подключение.
gcloud compute network-attachments create psc-network-attachment \
--region=us-central1 \
--connection-preference=ACCEPT_AUTOMATIC \
--subnets=intf-subnet
Список сетевых вложений
Внутри Cloud Shell выведите список сетевых подключений.
gcloud compute network-attachments list
Опишите сетевые вложения
Внутри Cloud Shell опишите сетевое подключение.
gcloud compute network-attachments describe psc-network-attachment --region=us-central1
Запишите имя сетевого прикрепления PSC, psc-network-attachment
, которое будет использоваться производителем при создании интерфейса подключения частной службы.
Чтобы просмотреть URL-адрес сетевого прикрепления PSC в Cloud Console, перейдите по следующему пути:
Сетевые службы → Подключение частной службы → Сетевое подключение → psc-network-attachment
7. Частная DNS-зона
Вы создадите зону Cloud DNS для demo.com
и добавите в неё запись A, указывающую на IP-адреса вашей прокси-виртуальной машины. Позже в Agent Engine будет развёрнут DNS-пиринг, который обеспечит доступ к DNS-записям потребителя.
Внутри Cloud Shell выполните следующие действия, чтобы создать DNS-имя demo.com.
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"
Получите и сохраните IP-адреса экземпляров, используемых для записей DNS A.
Внутри Cloud Shell выполните описание экземпляров виртуальных машин.
gcloud compute instances describe proxy-vm --zone=us-central1-a | grep networkIP:
Внутри Cloud Shell создайте набор записей для виртуальной машины proxy-vm.demo.com, обязательно обновите IP-адрес на основе выходных данных вашей среды.
gcloud dns --project=$projectid record-sets create proxy-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.2"
Создайте правило облачного брандмауэра, чтобы разрешить доступ из интерфейса PSC.
В следующем разделе создайте правило брандмауэра, которое разрешает трафику, исходящему из сетевого подключения PSC, доступ к proxy-vm в Consumer VPC.
В Cloud Shell создайте правило входящего брандмауэра.
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
В следующем разделе описывается создание Jupyter Notebook. Этот блокнот будет использоваться для развертывания Agent Engine, ориентированного на явный прокси-сервер для исходящего интернет-трафика.
Создайте учетную запись службы, управляемую пользователем
В следующем разделе вы создадите учетную запись службы, которая будет связана с экземпляром Vertex AI Workbench, используемым в этом руководстве.
В этом руководстве к учетной записи службы будут применены следующие роли:
- Администратор хранилища
- Пользователь Vertex AI
- Администратор реестра артефактов
- Пользователь учетной записи службы IAM
Внутри Cloud Shell создайте учетную запись службы.
gcloud iam service-accounts create notebook-sa \
--display-name="notebook-sa"
Внутри Cloud Shell обновите учетную запись службы, назначив ей роль администратора хранилища.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"
Внутри Cloud Shell обновите учетную запись службы, добавив роль Vertex AI User.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"
Внутри Cloud Shell обновите учетную запись службы, назначив ей роль Artifact Registry Admin.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"
Внутри Cloud Shell разрешите учетной записи службы блокнота использовать учетную запись службы 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"
9. Обновите явный прокси-сервер.
В следующем разделе вам нужно будет подключиться по SSH к явному прокси-серверу и обновить файл конфигурации tinyproxy.conf, а затем выполнить сброс настроек.
Из Cloud Shell
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Откройте файл конфигурации tinyproxy и обновите его с помощью редактора или по вашему выбору. Ниже приведён пример использования 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
В следующем разделе создайте экземпляр Vertex AI Workbench, который включит ранее созданную учетную запись службы notebook-sa.
Внутри Cloud Shell создайте экземпляр частного клиента.
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. Обновление агента службы Vertex AI
Vertex AI действует от вашего имени, выполняя такие операции, как получение IP-адреса из подсети сетевого подключения PSC, используемой для создания интерфейса PSC. Для этого Vertex AI использует агент сервиса (указан ниже), требующий разрешения администратора сети :
service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com
Внутри Cloud Shell получите номер вашего проекта.
gcloud projects describe $projectid | grep projectNumber
Внутри Cloud Shell задайте номер вашего проекта.
projectnumber=YOUR-PROJECT-Number
В Cloud Shell создайте учётную запись службы для AI Platform. Пропустите этот шаг, если в вашем проекте уже есть учётная запись службы.
gcloud beta services identity create --service=aiplatform.googleapis.com --project=$projectnumber
Внутри Cloud Shell обновите учетную запись агента службы, назначив ей роль compute.networkAdmin.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/compute.networkAdmin"
Внутри Cloud Shell обновите учетную запись агента службы с ролью dns.peer.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/dns.peer"
Обновление учетной записи службы по умолчанию
Предоставьте вашей учётной записи службы по умолчанию доступ к Vertex AI. Обратите внимание, что изменение прав доступа может вступить в силу с течением времени.
Внутри Cloud Shell обновите учетную запись службы по умолчанию с ролью aiplatform.user.
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/aiplatform.user"
12. Прокси-VM Tcpdump
Для проверки IP-подключения из Agent Engine мы можем использовать TCPDUMP. Это позволит нам наблюдать за соединением, исходящим из подсети PSC Network Attachment, 192.168.10.0/28, при вызове запроса GET из Agent Engine на публичный URL-адрес.
Из Cloud Shell ssh в прокси-виртуальную машину.
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Из ОС proxy-vm выполните tcpdump.
sudo tcpdump -i any net 192.168.10.0/28 -nn
13. Развертывание агентского движка
Примечание: для выполнения задач в этом разделе мы будем использовать консоль GCP и блокнот JupyterLab.
В следующем разделе вы создадите блокнот, который будет выполнять следующие задачи:
- Использует Frankfurter API (https://api.frankfurter.app/) для получения данных о курсе обмена валют
- Ссылается на явный прокси-сервер (proxy_server), нацеленный на proxy-vm в потребительском vpc, используя полное доменное имя proxy-vm.demo.com.
- Определите dnsPeeringConfigs "домен": "demo.com."
Запустите задание обучения в экземпляре Vertex AI Workbench.
- В консоли Google Cloud перейдите в Vertex AI → Workbench.
- Рядом с именем вашего экземпляра Vertex AI Workbench (workbench-tutorial) нажмите «Открыть JupyterLab». Ваш экземпляр Vertex AI Workbench откроется в JupyterLab.
- Выберите Файл > Создать > Блокнот.
- Выберите Ядро > Python 3
Установите необходимые библиотеки Python: установите библиотеки, необходимые для Agent Engine, включая pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys и langchain-google-vertexai.
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
!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: убедитесь, что вновь установленные библиотеки загружены правильно.
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
# Restart the notebook kernel after install, so you can run langchain successfully.
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)
Задайте переменные проекта и контейнера: определите идентификатор проекта Google Cloud, номер проекта, имя службы, каталог GCS, конечную точку, имя контейнера и местоположение.
Обновите следующие поля перед запуском ячейки
- PROJECT_ID = "введите идентификатор вашего проекта"
- PROJECT_NUMBER = "введите номер вашего проекта"
- BUCKET= "введите уникальное имя контейнера"
Примечание: на следующем шаге мы будем использовать переменную BUCKET для создания контейнера облачного хранилища.
В блокноте JupyterLab создайте новую ячейку, обновите и выполните следующее.
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: создайте контейнер облачного хранилища для хранения кода агента.
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
!gcloud storage buckets create gs://{BUCKET}
Определите имя сетевого подключения: укажите имя вашего сетевого подключения Private Service Connect.
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
NETWORK_ATTACHMENT_NAME = 'psc-network-attachment' #@param {type:"string"}
Инициализируйте клиентские библиотеки Python: настройте необходимые клиентские библиотеки для сервисов Google Cloud.
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
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)
Настройте агент и инструменты: определите класс StreamingAgent и функцию get_exchange_rate для получения курсов обмена валют с использованием API Frankfurter через явный прокси-сервер.
В блокноте JupyterLab создайте новую ячейку и запустите приведенную ниже конфигурацию, обратите внимание на следующие моменты:
- Функция def get_exchange_rate будет использовать API Frankfurter (https://api.frankfurter.app/) для получения данных о курсе обмена.
- proxy_server = "http://proxy-vm.demo.com:8888". Полное доменное имя (FQDN) связано с прокси-виртуальной машиной, развёрнутой в потребительской VPC. Мы используем DNS-пиринг для разрешения полного доменного имени на более позднем этапе.
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()
Загрузите файлы агента в облачное хранилище: загрузите сериализованный агент и его требования в указанный вами контейнер GCS.
В блокноте JupyterLab создайте новую ячейку и выполните следующее:
# 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: разверните Agent Engine, настройте его с помощью интерфейса PSC и DNS-пиринга для разрешения полного доменного имени прокси-машины в потребительском VPC.
В блокноте JupyterLab создайте и запустите ячейку ниже, обратите внимание на следующие моменты:
- DNS-пиринг для VPC-клиентов настраивается с помощью dnsPeeringConfigs (dnsPeeringConfigs) для доменного имени demo.com.
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)
Мониторинг статуса развертывания: проверка статуса операции развертывания Agent Engine.
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
operation_id = json.loads(response.content)["name"].split("/")[7]
pprint.pprint(operation_id)
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
Примечание: эта операция может занять около 5 минут. Перезапустите ячейку, чтобы проверить ход выполнения. Не переходите к следующему разделу, пока не увидите результат, аналогичный показанному на снимке экрана ниже.
# 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))
Пример успешного запуска:
Запрос развернутого агента: отправьте запрос развернутому агентскому модулю, чтобы проверить его функциональность.
В блокноте JupyterLab создайте новую ячейку и выполните следующее.
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)
Результаты потокового запроса: потоковая передача выходных данных запроса Agent Engine.
В блокноте JupyterLab создайте новую ячейку и выполните следующую команду, которая инициирует вызов API к общедоступному URL-адресу с использованием явного прокси-сервера в VPC потребителей.
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))
Пример успешного запуска:
14. Проверка Tcpdump
Просмотрите выходные данные tcpdump, в которых подробно описывается связь между IP-адресом сетевого подключения PSC, используемым Agent Engine, и Prox-VM при отправке запроса.
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
Вы также можете просмотреть IP-адреса сетевых подключений, используемые Agent Engine, перейдя по следующей ссылке:
Сетевые службы → Подключение частной службы → Сетевое подключение → psc-network-attachment
Выберите проект-арендатор (имя проекта заканчивается на -tp)
Выделенное поле обозначает IP-адрес, используемый Agent Engine из сетевого подключения PSC.
16. Проверка облачного логирования
Выйдите из сеанса proxy-vm TCPDump и выполните команду PING на Frankfurter api.frankfurter.app, чтобы получить соответствующий публичный IP-адрес.
ping -c4 api.frankfurter.app
Пример определяет 104.26.1.198 как публичный IP-адрес для api.frankfurter.app.
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
Давайте посмотрим на ведение журнала NAT, чтобы увидеть, наблюдается ли трафик для 104.26.1.198.
Перейдите к следующему:
Мониторинг → Обозреватель журналов
Используйте следующий фильтр:
resource.type="nat_gateway"
Выберите период времени, затем выполните запрос.
Разверните запись журнала, в которой указан (целевой) публичный IP-адрес (104.26.1.198) api.frankfurter.app, а также исходный IP-адрес и имя proxy-vm, которая подтверждает использование явного прокси-сервера для выхода в Интернет.
17. Уборка
В блокноте JupyterLab создайте новую ячейку и выполните следующую команду, которая приведет к удалению развертывания Agent Engine.
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)
Из 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. Поздравления
Поздравляем, вы успешно настроили и проверили Agent Engine, развернутый с интерфейсом Private Service Connect, с выходом в Интернет, осуществляемым через явный прокси-сервер.
Вы создали инфраструктуру потребителя и добавили сетевое подключение, которое позволило производителю создать виртуальную машину с несколькими сетевыми картами для связи потребителя и производителя. Вы научились создавать явный прокси-сервер и DNS-пиринг, обеспечивающий подключение к Интернету.
Cosmopup считает, что обучающие материалы — это здорово!