Proxy tường minh PSC của Agent Engine

1. Giới thiệu

Giao diện Private Service Connect là một tài nguyên cho phép mạng Đám mây riêng ảo (VPC) của nhà sản xuất bắt đầu kết nối với nhiều đích đến trong mạng VPC của người dùng. Mạng nhà sản xuất và mạng người tiêu dùng có thể nằm trong các dự án và tổ chức khác nhau.

Nếu một tệp đính kèm mạng chấp nhận kết nối từ một giao diện Kết nối dịch vụ riêng tư, thì Google Cloud sẽ phân bổ cho giao diện đó một địa chỉ IP từ mạng con của người dùng do tệp đính kèm mạng chỉ định. Các mạng lưới người tiêu dùng và nhà sản xuất được kết nối và có thể giao tiếp bằng cách sử dụng địa chỉ IP nội bộ.

Mối kết nối giữa một tệp đính kèm mạng và một giao diện Private Service Connect tương tự như mối kết nối giữa một điểm cuối Private Service Connect và một tệp đính kèm dịch vụ, nhưng có 2 điểm khác biệt chính:

  • Tệp đính kèm mạng cho phép mạng nhà sản xuất bắt đầu kết nối với mạng người tiêu dùng (dịch vụ được quản lý theo chiều đi), trong khi điểm cuối cho phép mạng người tiêu dùng bắt đầu kết nối với mạng nhà sản xuất (dịch vụ được quản lý theo chiều đến).
  • Kết nối giao diện Private Service Connect là kết nối bắc cầu. Điều này có nghĩa là mạng nhà sản xuất có thể giao tiếp với các mạng khác được kết nối với mạng người tiêu dùng.

Những điểm cần cân nhắc về khả năng tiếp cận PSC-Interface của Vertex AI

  • PSC-Interface có khả năng định tuyến lưu lượng truy cập đến VPC hoặc các đích đến tại chỗ trong khối địa chỉ RFC1918.
  • PSC-Interface nhắm đến các khối địa chỉ không phải rfc-1918 yêu cầu một proxy rõ ràng được triển khai trong VPC của người dùng có địa chỉ rfc-1918. Trong quá trình triển khai Vertex AI, bạn phải xác định proxy cùng với FQDN của điểm cuối mục tiêu.
  • Khi bạn chỉ định cấu hình triển khai bằng Giao diện PSC, cấu hình đó sẽ giữ lại quyền truy cập Internet mặc định. Lưu lượng truy cập đi ra này sẽ thoát trực tiếp từ mạng lưới người thuê an toàn do Google quản lý.

Những điểm cần lưu ý về VPC-SC PSC-Interface của Vertex AI

  • Khi dự án của bạn nằm trong ranh giới VPC Service Controls, quyền truy cập Internet mặc định của các đối tượng thuê do Google quản lý sẽ bị ranh giới chặn để ngăn chặn hành vi trích xuất dữ liệu.
  • Để cho phép hoạt động triển khai truy cập vào Internet công cộng trong trường hợp này, bạn phải định cấu hình rõ ràng một đường dẫn truyền dữ liệu an toàn để định tuyến lưu lượng truy cập thông qua VPC của bạn.
  • Cách được đề xuất để thực hiện việc này là thiết lập một máy chủ proxy bên trong chu vi VPC bằng địa chỉ RFC1918 và tạo một cổng Cloud NAT để cho phép VM proxy truy cập vào Internet.

Để biết thêm thông tin, hãy tham khảo các tài nguyên sau:

Triển khai một tác nhân | AI tạo sinh trên Vertex AI | Google Cloud

Thiết lập giao diện Private Service Connect cho các tài nguyên Vertex AI | Google Cloud

Sản phẩm bạn sẽ tạo ra

Trong hướng dẫn này, bạn sẽ tạo một Agent Engine toàn diện được triển khai bằng Giao diện Kết nối dịch vụ riêng tư (PSC) để cho phép kết nối với một trang web công khai (https://api.frankfurter.app/) thông qua một VM Proxy được triển khai trong VPC của người dùng bằng địa chỉ RFC1918. Ví dụ về việc triển khai này có thể áp dụng trong một dự án có bật VPC-SC hoặc cho những quản trị viên yêu cầu lưu lượng truy cập internet đi ra thông qua mạng của khách hàng thay vì vpc của đối tượng thuê.

Hình 1

f42f2db921f6d5af.png

Bạn sẽ tạo một psc-network-attachment duy nhất trong VPC của người tiêu dùng bằng cách tận dụng tính năng kết nối ngang hàng DNS để phân giải proxy-vm mạng của người tiêu dùng trong dự án người thuê nhà lưu trữ Agent Engine, dẫn đến các trường hợp sử dụng sau:

Triển khai Agent Engine và định cấu hình một máy ảo proxy để hoạt động như một proxy tường minh, cho phép máy ảo này truy cập vào một URL công khai https://api.frankfurter.app

Kiến thức bạn sẽ học được

  • Cách tạo thiết bị lưu trữ mạng
  • Cách nhà sản xuất có thể sử dụng tệp đính kèm mạng để tạo giao diện PSC
  • Cách thiết lập giao tiếp từ nhà sản xuất đến người tiêu dùng bằng cách sử dụng tính năng DNS Peering
  • Cách triển khai và sử dụng vm proxy để truyền dữ liệu ra bên ngoài Internet

Bạn cần có

Dự án trên Google Cloud

Quyền IAM

2. Trước khi bắt đầu

Cập nhật dự án để hỗ trợ hướng dẫn

Hướng dẫn này sử dụng $variables để hỗ trợ việc triển khai cấu hình gcloud trong Cloud Shell.

Trong Cloud Shell, hãy thực hiện các bước sau:

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

Bật API

Trong Cloud Shell, hãy thực hiện các bước sau:

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"

Xác minh rằng các API đã được bật thành công

gcloud services list --enabled

3. Thiết lập người tiêu dùng

Tạo VPC người tiêu dùng

VPC này nằm trong một dự án của khách hàng. Các tài nguyên sau đây sẽ được tạo trong VPC này

  • Mạng con dành cho người tiêu dùng
  • Mạng con đính kèm mạng
  • Cloud Router (Bắt buộc đối với Cloud NAT)
  • Cloud NAT

Trong Cloud Shell, hãy thực hiện các bước sau:

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

Tạo mạng con của người tiêu dùng

Trong Cloud Shell, hãy tạo mạng con cho VM Proxy:

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

Tạo mạng con Đính kèm mạng Kết nối dịch vụ riêng tư

Trong Cloud Shell, hãy tạo mạng con cho PSC Network Attachment:

gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1

Cấu hình Cloud Router và NAT

Trong hướng dẫn này, Cloud NAT được dùng để cung cấp quyền truy cập Internet cho VM proxy (không có địa chỉ IP công khai). Cloud NAT giúp các máy ảo chỉ có địa chỉ IP riêng tư kết nối với Internet, cho phép các máy ảo này thực hiện những tác vụ như cài đặt các gói phần mềm.

Trong Cloud Shell, hãy tạo Cloud Router.

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

Trong Cloud Shell, hãy tạo cổng NAT có bật tính năng ghi nhật ký. Chúng tôi sẽ sử dụng nhật ký để xác thực quyền truy cập vào ip công khai cho 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. Bật IAP

Để cho phép IAP kết nối với các phiên bản máy ảo, hãy tạo một quy tắc tường lửa có:

  • Áp dụng cho tất cả các phiên bản máy ảo mà bạn muốn có thể truy cập bằng IAP.
  • Cho phép lưu lượng truy cập vào từ dải IP 35.235.240.0/20. Dải địa chỉ này chứa tất cả địa chỉ IP mà IAP sử dụng để chuyển tiếp TCP.

Trong Cloud Shell, hãy tạo quy tắc tường lửa IAP.

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

5. Tạo phiên bản máy ảo cho người tiêu dùng

Trong Cloud Shell, hãy tạo phiên bản máy ảo người dùng, proxy-vm, đóng vai trò là proxy rõ ràng cho Agent Engine. Chúng ta sẽ sử dụng tinyproxy làm ứng dụng để chuyển lưu lượng truy cập HTTP qua proxy.

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. Tệp đính kèm mạng Kết nối dịch vụ riêng tư

Tệp đính kèm mạng là tài nguyên theo khu vực, đại diện cho phía người dùng của một giao diện Private Service Connect. Bạn liên kết một mạng con duy nhất với một tệp đính kèm mạng và nhà sản xuất sẽ chỉ định IP cho giao diện Private Service Connect từ mạng con đó. Mạng con phải ở cùng khu vực với thiết bị đính kèm mạng. Thiết bị đính kèm mạng phải ở cùng khu vực với dịch vụ nhà sản xuất.

Tạo tệp đính kèm mạng

Trong Cloud Shell, hãy tạo tệp đính kèm mạng.

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

Liệt kê các tệp đính kèm mạng

Trong Cloud Shell, hãy liệt kê các tệp đính kèm mạng.

gcloud compute network-attachments list

Mô tả các tệp đính kèm mạng

Trong Cloud Shell, hãy mô tả network attachment.

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

Ghi lại tên Network Attachment của PSC, psc-network-attachment, mà nhà sản xuất sẽ sử dụng khi tạo Giao diện Kết nối dịch vụ riêng tư.

Để xem URL của Network Attachment (Tệp đính kèm mạng) PSC trong Cloud Console, hãy chuyển đến:

Network Services (Dịch vụ mạng) → Private Service Connect (Kết nối dịch vụ riêng tư) → Network Attachment (Tệp đính kèm mạng) → psc-network-attachment

8eec51cb197da218.png

7. Vùng DNS riêng

Bạn sẽ tạo một Vùng DNS trên đám mây cho demo.com và điền sẵn một bản ghi A trỏ đến địa chỉ IP của proxy-vm. Sau đó, tính năng kết nối ngang DNS sẽ được triển khai trong Agent Engine, cho phép truy cập vào các bản ghi DNS của người dùng.

Trong Cloud Shell, hãy thực hiện các bước sau để tạo một bản minh hoạ tên 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"

Lấy và lưu trữ Địa chỉ IP của các phiên bản được dùng cho bản ghi DNS A.

Trong Cloud Shell, hãy thực hiện thao tác mô tả đối với các thực thể máy ảo.

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

Trong Cloud Shell, hãy tạo bộ bản ghi cho VM, proxy-vm.demo.com, nhớ cập nhật địa chỉ IP dựa trên đầu ra của môi trường.

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

Tạo quy tắc Tường lửa trên đám mây để cho phép truy cập từ Giao diện PSC

Trong phần sau, hãy tạo một quy tắc tường lửa cho phép lưu lượng truy cập bắt nguồn từ PSC Network Attachment truy cập vào proxy-vm trong VPC của người dùng.

Trong Cloud Shell, hãy tạo quy tắc tường lửa cho lưu lượng truy cập vào.

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. Tạo một sổ tay Jupyter

Phần sau đây hướng dẫn bạn cách tạo một Sổ tay Jupyter. Sổ tay này sẽ được dùng để triển khai Agent Engine nhắm đến một proxy rõ ràng cho Internet Egress.

Tạo tài khoản dịch vụ do người dùng quản lý

Trong phần sau, bạn sẽ tạo một tài khoản dịch vụ được liên kết với phiên bản Vertex AI Workbench dùng trong hướng dẫn này.

Trong hướng dẫn này, tài khoản dịch vụ sẽ có các vai trò sau:

Trong Cloud Shell, hãy tạo tài khoản dịch vụ.

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

Trong Cloud Shell, hãy cập nhật tài khoản dịch vụ bằng vai trò Quản trị viên bộ nhớ.

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

Trong Cloud Shell, hãy cập nhật tài khoản dịch vụ bằng vai trò Người dùng Vertex AI.

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

Trong Cloud Shell, hãy cập nhật tài khoản dịch vụ bằng vai trò Quản trị viên Artifact Registry.

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

Trong Cloud Shell, hãy cho phép tài khoản dịch vụ sổ tay sử dụng tài khoản dịch vụ mặc định của 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. Cập nhật proxy tường minh

Trong phần sau, bạn sẽ cần ssh vào proxy tường minh và cập nhật tệp cấu hình tinyproxy.conf, sau đó thực hiện thao tác đặt lại.

Từ Cloud Shell

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

Mở tệp cấu hình tinyproxy, cập nhật bằng trình chỉnh sửa hoặc lựa chọn của bạn. Dưới đây là ví dụ về cách sử dụng 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. Tạo một phiên bản Vertex AI Workbench

Trong phần sau, hãy tạo một phiên bản Vertex AI Workbench kết hợp tài khoản dịch vụ đã tạo trước đó, notebook-sa.

Tạo phiên bản ứng dụng khách riêng tư trong 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. Cập nhật tác nhân dịch vụ Vertex AI

Vertex AI thay mặt bạn thực hiện các thao tác như lấy Địa chỉ IP từ mạng con PSC Network Attachment (Tệp đính kèm mạng PSC) dùng để tạo Giao diện PSC. Để làm như vậy, Vertex AI sử dụng một tác nhân dịch vụ (được liệt kê bên dưới) yêu cầu quyền Quản trị viên mạng:

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

Trong Cloud Shell, hãy lấy số dự án của bạn.

gcloud projects describe $projectid | grep projectNumber

Trong Cloud Shell, hãy đặt số dự án của bạn.

projectnumber=YOUR-PROJECT-Number

Trong Cloud Shell, hãy tạo một tài khoản dịch vụ cho AI Platform. Bỏ qua bước này nếu bạn đã có tài khoản dịch vụ trong dự án của mình.

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

Trong Cloud Shell, hãy cập nhật tài khoản đơn vị hỗ trợ dịch vụ bằng vai trò compute.networkAdmin.

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

Trong Cloud Shell, hãy cập nhật tài khoản đơn vị hỗ trợ dịch vụ bằng vai trò dns.peer

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

Cập nhật tài khoản dịch vụ mặc định

Cấp cho tài khoản dịch vụ mặc định của bạn quyền truy cập vào Vertex AI. Xin lưu ý rằng có thể mất một thời gian để thay đổi về quyền truy cập có hiệu lực.

Trong Cloud Shell, hãy cập nhật tài khoản dịch vụ mặc định bằng vai trò aiplatform.user

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

12. Proxy VM Tcpdump

Để xác thực khả năng kết nối IP từ Agent Engine, chúng ta có thể sử dụng TCPDUMP. Điều này sẽ cho phép chúng tôi quan sát hoạt động giao tiếp bắt nguồn từ mạng con PSC Network Attachment, 192.168.10.0/28 khi gọi yêu cầu get từ Agent Engine đến URL công khai.

Từ Cloud Shell, hãy ssh vào vm proxy.

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

Từ hệ điều hành proxy-vm, hãy thực thi tcpdump.

sudo tcpdump -i any net 192.168.10.0/28 -nn

13. Triển khai Agent Engine

Lưu ý: Chúng ta sẽ sử dụng bảng điều khiển GCP và sổ tay JupyterLab để hoàn thành các tác vụ trong phần này

Trong phần sau, bạn sẽ tạo một sổ tay thực hiện các nhiệm vụ sau:

  • Sử dụng Frankfurter API (https://api.frankfurter.app/) để lấy dữ liệu về tỷ giá hối đoái
  • Tham chiếu đến một proxy rõ ràng (proxy_server) nhắm đến proxy-vm trong vpc của người dùng bằng cách sử dụng FQDN proxy-vm.demo.com
  • Xác định dnsPeeringConfigs "domain": "demo.com."

Chạy quy trình huấn luyện trong phiên bản Vertex AI Workbench.

  • Trong Google Cloud Console, hãy chuyển đến Vertex AI → Workbench
  • Bên cạnh tên phiên bản Vertex AI Workbench (workbench-tutorial), hãy nhấp vào Open JupyterLab (Mở JupyterLab). Phiên bản Vertex AI Workbench của bạn sẽ mở ra trong JupyterLab.
  • Chọn Tệp > Mới > Sổ tay
  • Chọn Kernel > Python 3

Cài đặt các thư viện Python cần thiết: Cài đặt các thư viện cần thiết cho Agent Engine, bao gồm pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys và langchain-google-vertexai.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

!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

Khởi động lại nhân Jupyter Notebook: Đảm bảo các thư viện mới cài đặt được tải đúng cách.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

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

import IPython

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

Đặt các biến dự án và bộ chứa: Xác định mã dự án, số dự án, tên dịch vụ, thư mục GCS, điểm cuối, tên bộ chứa và vị trí của Google Cloud.

Cập nhật các trường sau trước khi bạn chạy ô

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

Lưu ý: Chúng ta sẽ dùng biến BUCKET để tạo một bộ chứa Cloud Storage ở bước tiếp theo.

Trong sổ tay JupyterLab, hãy tạo một ô mới, cập nhật và chạy nội dung sau.

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

Tạo một bộ chứa GCS: Tạo một bộ chứa Cloud Storage để lưu trữ mã tác nhân.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

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

Xác định tên của tài nguyên đính kèm mạng: Chỉ định tên của tài nguyên đính kèm mạng Private Service Connect.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

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

Khởi chạy thư viện ứng dụng Python: Thiết lập các thư viện ứng dụng cần thiết cho các dịch vụ của Google Cloud.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

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)

Định cấu hình tác nhân và công cụ: Xác định lớp StreamingAgent và hàm get_exchange_rate để tìm nạp tỷ giá hối đoái bằng Frankfurter API thông qua proxy rõ ràng.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy cấu hình bên dưới, lưu ý những điểm nổi bật sau:

  • Hàm def get_exchange_rate sẽ sử dụng Frankfurter API (https://api.frankfurter.app/) để lấy dữ liệu về tỷ giá hối đoái.
  • proxy_server = "http://proxy-vm.demo.com:8888" FQDN được liên kết với proxy vm được triển khai trong VPC của người tiêu dùng. Chúng ta sẽ sử dụng tính năng kết nối ngang DNS để phân giải FQDN ở bước sau.
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()

Tải tệp tác nhân lên Cloud Storage: Tải tác nhân được chuyển đổi tuần tự và các yêu cầu của tác nhân đó lên bộ chứa GCS được chỉ định.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau:

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

Triển khai Agent Engine: Triển khai Agent Engine, định cấu hình Agent Engine bằng giao diện PSC và tính năng ngang hàng DNS để phân giải FQDN của VM proxy trong VPC của người tiêu dùng.

Trong sổ tay JupyterLab, hãy tạo và chạy ô bên dưới, lưu ý những điểm nổi bật sau:

  • Tính năng DNS Peering (DNS ngang hàng) với VPC của người dùng được định cấu hình bằng dnsPeeringConfigs (dnsPeeringConfigs) cho tên miền 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)

Theo dõi trạng thái triển khai: Kiểm tra trạng thái của thao tác triển khai Agent Engine.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

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

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

Lưu ý: Thao tác này có thể mất khoảng 5 phút để hoàn tất. Chạy lại ô để kiểm tra tiến trình. Vui lòng không chuyển sang phần tiếp theo cho đến khi bạn thấy một đầu ra tương tự như ảnh chụp màn hình bên dưới.

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

Ví dụ về một lần chạy thành công:

3f6dcd1074af7651.png

Truy vấn nhân viên hỗ trợ đã triển khai: Gửi một truy vấn đến Agent Engine đã triển khai để kiểm thử chức năng của nhân viên hỗ trợ đó.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau.

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)

Truyền trực tuyến kết quả truy vấn: Truyền trực tuyến đầu ra từ truy vấn Agent Engine.

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy nội dung sau đây để kích hoạt lệnh gọi API đến URL công khai bằng cách sử dụng proxy rõ ràng trong VPC của người dùng.

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

Ví dụ về một lần chạy thành công:

1bd81d12426a348f.png

14. Xác thực Tcpdump

Xem đầu ra tcpdump trình bày chi tiết thông tin liên lạc giữa địa chỉ IP của PSC Network Attachment mà Agent Engine sử dụng và Prox-VM khi yêu cầu được đăng.

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. Xác thực giao diện PSC

Bạn cũng có thể xem các IP đính kèm mạng mà Agent Engine sử dụng bằng cách chuyển đến phần sau:

Network Services (Dịch vụ mạng) → Private Service Connect (Kết nối dịch vụ riêng tư) → Network Attachment (Tệp đính kèm mạng) → psc-network-attachment

Chọn dự án người thuê nhà (tên dự án kết thúc bằng -tp)

8a4b5a6e5dfd63d7.png

Trường được đánh dấu biểu thị địa chỉ IP mà Agent Engine sử dụng từ PSC Network Attachment.

c618359f6eafc0c6.png

16. Xác thực Cloud Logging

Thoát khỏi phiên TCPDump proxy-vm và thực hiện lệnh PING đến api.frankfurter.app của Frankfurter để lấy địa chỉ IP công khai được liên kết.

ping -c4 api.frankfurter.app 

Ví dụ xác định 104.26.1.198 là IP công khai cho 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

Hãy xem Nhật ký NAT để biết lưu lượng truy cập cho 104.26.1.198 có được ghi nhận hay không.

Chuyển đến:

Giám sát → Trình khám phá nhật ký

Sử dụng bộ lọc sau:

resource.type="nat_gateway"

31024dc29c39084.png

Chọn khoảng thời gian, sau đó chọn Chạy truy vấn

5976857e92d149d3.png

Mở rộng mục nhật ký xác định IP công khai (đích đến) (104.26.1.198) của api.frankfurter.app và địa chỉ IP nguồn cũng như tên của proxy-vm xác thực việc sử dụng proxy rõ ràng cho lưu lượng truy cập internet.

14e293a7fea68db4.png

17. Dọn dẹp

Trong sổ tay JupyterLab, hãy tạo một ô mới và chạy lệnh sau để kích hoạt việc xoá việc triển khai 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)

Trong Cloud Shell, hãy xoá các thành phần hướng dẫn.

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. Xin chúc mừng

Xin chúc mừng! Bạn đã định cấu hình và xác thực thành công Agent Engine được triển khai bằng Giao diện Private Service Connect với lưu lượng truy cập Internet được thực hiện thông qua một proxy rõ ràng.

Bạn đã tạo cơ sở hạ tầng người dùng và thêm một tệp đính kèm mạng cho phép nhà sản xuất tạo một máy ảo có nhiều NIC để kết nối thông tin liên lạc giữa người dùng và nhà sản xuất. Bạn đã tìm hiểu cách tạo một proxy rõ ràng và DNS peering cho phép kết nối Internet.

Cosmopup cho rằng các hướng dẫn rất hữu ích!!

c911c127bffdee57.jpeg

Tiếp theo là gì?

Tài liệu đọc thêm và video

Tài liệu tham khảo