Agent Engine PSC Explicit Proxy

۱. مقدمه

رابط اتصال سرویس خصوصی منبعی است که به یک شبکه ابر خصوصی مجازی (VPC) تولیدکننده اجازه می‌دهد تا اتصالاتی را به مقاصد مختلف در یک شبکه VPC مصرف‌کننده آغاز کند. شبکه‌های تولیدکننده و مصرف‌کننده می‌توانند در پروژه‌ها و سازمان‌های مختلف باشند.

اگر یک اتصال شبکه، اتصالی را از رابط Private Service Connect بپذیرد، Google Cloud یک آدرس IP از زیرشبکه مصرف‌کننده که توسط اتصال شبکه مشخص شده است، به رابط اختصاص می‌دهد. شبکه‌های مصرف‌کننده و تولیدکننده به هم متصل هستند و می‌توانند با استفاده از آدرس‌های IP داخلی ارتباط برقرار کنند.

اتصال بین یک اتصال شبکه و یک رابط Private Service Connect مشابه اتصال بین یک نقطه پایانی Private Service Connect و یک اتصال سرویس است، اما دو تفاوت کلیدی دارد:

  • یک اتصال شبکه به شبکه تولیدکننده اجازه می‌دهد تا اتصالاتی را به شبکه مصرف‌کننده آغاز کند (خروجی سرویس مدیریت‌شده)، در حالی که یک نقطه پایانی به شبکه مصرف‌کننده اجازه می‌دهد تا اتصالاتی را به شبکه تولیدکننده آغاز کند (ورودی سرویس مدیریت‌شده).
  • اتصال رابط Private Service Connect از نوع انتقالی است. این بدان معناست که یک شبکه تولیدکننده می‌تواند با شبکه‌های دیگری که به شبکه مصرف‌کننده متصل هستند، ارتباط برقرار کند.

ملاحظات دسترسی‌پذیری رابط کاربری PSC در Vertex AI

  • رابط PSC قادر به مسیریابی ترافیک به VPC یا مقصدهای مبتنی بر on-premesis در بلوک آدرس RFC1918 است.
  • رابط PSC که بلوک‌های آدرس غیر rfc-1918 را هدف قرار می‌دهد، نیاز به یک پروکسی صریح مستقر در VPC مصرف‌کننده با آدرس rfc-1918 دارد. در استقرار Vertex AI، پروکسی باید به همراه یک FQDN از نقطه پایانی هدف تعریف شود.
  • وقتی که شما سیستم خود را فقط با رابط PSC پیکربندی می‌کنید، دسترسی پیش‌فرض به اینترنت حفظ می‌شود. این ترافیک خروجی مستقیماً از شبکه امن و تحت مدیریت گوگل خارج می‌شود.

ملاحظات رابط VPC-SC در Vertex AI PSC

  • وقتی پروژه شما بخشی از محیط کنترل‌های سرویس VPC است، دسترسی پیش‌فرض اینترنت مستاجران تحت مدیریت گوگل توسط محیط مسدود می‌شود تا از نشت داده‌ها جلوگیری شود.
  • برای اینکه در این سناریو به استقرار اجازه دسترسی به اینترنت عمومی داده شود، باید صریحاً یک مسیر خروجی امن پیکربندی کنید که ترافیک را از طریق VPC شما هدایت کند.
  • راه پیشنهادی برای دستیابی به این هدف، راه‌اندازی یک سرور پروکسی در محیط VPC شما با آدرس RFC1918 و ایجاد یک دروازه Cloud NAT است تا به ماشین مجازی پروکسی اجازه دسترسی به اینترنت را بدهد.

برای اطلاعات تکمیلی، به منابع زیر مراجعه کنید:

استقرار یک عامل | هوش مصنوعی مولد روی Vertex AI | گوگل کلود

راه‌اندازی رابط اتصال سرویس خصوصی برای منابع هوش مصنوعی Vertex | گوگل کلود

آنچه خواهید ساخت

در این آموزش، شما قصد دارید یک موتور عامل جامع با رابط کاربری Private Service Connect (PSC) بسازید تا امکان اتصال به یک سایت عمومی (https://api.frankfurter.app/) را از طریق یک ماشین مجازی پروکسی مستقر در VPC مصرف‌کننده با آدرس RFC1918 فراهم کند. این نمونه استقرار در یک پروژه با قابلیت VPC-SC یا برای مدیرانی که نیاز به خروجی اینترنت از طریق شبکه مشتریان به جای VPC مستاجر دارند، قابل اجرا است.

شکل ۱

f42f2db921f6d5af.png

شما یک psc-network-attachment واحد در VPC مصرف‌کننده ایجاد خواهید کرد که از DNS peering برای حل مشکل proxy-vm شبکه مصرف‌کننده در پروژه مستاجر میزبان Agent Engine استفاده می‌کند و موارد استفاده زیر را به همراه خواهد داشت:

موتور عامل را مستقر کنید و یک ماشین مجازی پروکسی را طوری پیکربندی کنید که به عنوان یک پروکسی صریح عمل کند و به آن اجازه دهد به یک URL عمومی https://api.frankfurter.app دسترسی پیدا کند.

آنچه یاد خواهید گرفت

  • نحوه ایجاد پیوست شبکه
  • چگونه یک تولیدکننده می‌تواند از یک اتصال شبکه برای ایجاد رابط PSC استفاده کند
  • نحوه برقراری ارتباط از تولیدکننده به مصرف‌کننده با استفاده از DNS Peering
  • نحوه استقرار و استفاده از یک ماشین مجازی پروکسی برای خروجی اینترنت

آنچه نیاز دارید

پروژه ابری گوگل

مجوزهای IAM

۲. قبل از شروع

پروژه را برای پشتیبانی از آموزش به‌روزرسانی کنید

این آموزش از متغیرها (variables) برای کمک به پیاده‌سازی پیکربندی 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

۳. تنظیمات مصرف‌کننده

ایجاد VPC مصرف‌کننده

این VPC در یک پروژه مشتری قرار دارد. منابع زیر در این VPC ایجاد خواهند شد.

  • زیرشبکه مصرف‌کننده
  • زیرشبکه پیوست شبکه
  • روتر ابری (برای Cloud NAT مورد نیاز است)
  • NAT ابری

درون Cloud Shell، موارد زیر را انجام دهید:

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

زیرشبکه‌های مصرف‌کننده را ایجاد کنید

درون Cloud Shell، زیرشبکه (subnet) را برای ماشین مجازی پروکسی (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 Network Attachment subnet) را ایجاد کنید.

درون Cloud Shell، زیرشبکه‌ای برای PSC Network Attachment ایجاد کنید:

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، روتر ابری را ایجاد کنید.

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

درون Cloud Shell، یک دروازه NAT با قابلیت ثبت وقایع (logging) ایجاد کنید. ما از ثبت وقایع برای اعتبارسنجی دسترسی به 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

۴. فعال کردن پرداخت درون برنامه‌ای (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

۵. ایجاد نمونه‌های ماشین مجازی مصرف‌کننده

در داخل Cloud Shell، نمونه ماشین مجازی مصرف‌کننده، proxy-vm، را ایجاد کنید که به عنوان پروکسی صریح برای Agent Engine عمل خواهد کرد. ما از tinyproxy به عنوان برنامه‌ای برای پروکسی ترافیک HTTP استفاده خواهیم کرد.

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"

۶. اتصال شبکه سرویس خصوصی

پیوست‌های شبکه، منابع منطقه‌ای هستند که نمایانگر سمت مصرف‌کننده‌ی یک رابط 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 ، را که توسط تولیدکننده هنگام ایجاد رابط اتصال سرویس خصوصی استفاده خواهد شد، یادداشت کنید.

برای مشاهده آدرس اینترنتی پیوست شبکه PSC در Cloud Console، به مسیر زیر بروید:

سرویس‌های شبکه → اتصال سرویس خصوصی → پیوست شبکه → psc-network-attachment

8eec51cb197da218.png

۷. منطقه DNS خصوصی

شما یک منطقه DNS ابری برای demo.com ایجاد خواهید کرد و آن را با یک رکورد A که به آدرس‌های IP ماشین مجازی پروکسی شما اشاره می‌کند، پر خواهید کرد. بعداً، DNS peering در Agent Engine مستقر خواهد شد که امکان دسترسی به رکوردهای 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 Network Attachment اجازه دسترسی به 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

۸. یک دفترچه یادداشت ژوپیتر ایجاد کنید

بخش بعدی شما را در ایجاد یک Jupyter Notebook راهنمایی می‌کند. این Notebook برای استقرار Agent Engine که یک پروکسی صریح برای Internet Egress را هدف قرار می‌دهد، استفاده خواهد شد.

ایجاد یک حساب کاربری مدیریت‌شده توسط کاربر

در بخش بعدی، یک حساب کاربری سرویس ایجاد خواهید کرد که با نمونه Vertex AI Workbench که در آموزش استفاده شده است، مرتبط خواهد بود.

در این آموزش، حساب کاربری سرویس نقش‌های زیر را خواهد داشت:

در داخل Cloud Shell، حساب کاربری سرویس را ایجاد کنید.

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

در داخل Cloud Shell، حساب کاربری سرویس را با نقش Storage Admin به‌روزرسانی کنید.

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"

۹. پروکسی صریح را به‌روزرسانی کنید

در بخش بعدی، باید از طریق ssh به پروکسی صریح دسترسی پیدا کنید و فایل پیکربندی tinyproxy.conf را به‌روزرسانی کنید و سپس آن را ریست کنید.

از پوسته ابری

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

۱۰. یک نمونه از میز کار Vertex AI ایجاد کنید

در بخش بعدی، یک نمونه 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

۱۱. به‌روزرسانی عامل سرویس هوش مصنوعی ورتکس

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، یک حساب کاربری سرویس برای پلتفرم هوش مصنوعی ایجاد کنید. اگر در پروژه خود یک حساب کاربری سرویس دارید، از این مرحله صرف نظر کنید.

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"

۱۲. دستور Tcpdump برای ماشین مجازی پروکسی

برای اعتبارسنجی اتصال IP از Agent Engine، می‌توانیم از TCPDUMP استفاده کنیم. این به ما امکان می‌دهد هنگام فراخوانی درخواست get از Agent Engine به URL عمومی، ارتباطاتی را که از زیرشبکه PSC Network Attachment، یعنی 192.168.10.0/28، نشأت می‌گیرد، مشاهده کنیم.

از 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

۱۳. موتور عامل را مستقر کنید

توجه: ما برای انجام وظایف این بخش از کنسول GCP و نوت‌بوک JupyterLab استفاده خواهیم کرد.

در بخش زیر، شما یک دفترچه یادداشت ایجاد خواهید کرد که وظایف زیر را انجام می‌دهد:

  • از API فرانکفورتر (https://api.frankfurter.app/) برای دریافت داده‌های نرخ ارز استفاده می‌کند
  • به یک پروکسی صریح (proxy_server) اشاره می‌کند که proxy-vm را در vpc مصرف‌کننده با استفاده از FQDN هدف قرار می‌دهد. proxy-vm.demo.com
  • تعریف dnsPeeringConfigs برای "domain": "demo.com."

کار آموزشی را در نمونه Vertex AI Workbench اجرا کنید.

  • در کنسول گوگل کلود، به مسیر Vertex AI → Workbench بروید.
  • در کنار نام نمونه Vertex AI Workbench خود (workbench-tutorial)، روی Open JupyterLab کلیک کنید. نمونه Vertex AI Workbench شما در JupyterLab باز می‌شود.
  • فایل > جدید > دفترچه یادداشت را انتخاب کنید
  • هسته > پایتون ۳ را انتخاب کنید

نصب کتابخانه‌های پایتون لازم: کتابخانه‌های مورد نیاز برای 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 برای ایجاد یک باکت فضای ذخیره‌سازی ابری استفاده خواهیم کرد.

در نوت‌بوک 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"}

مقداردهی اولیه کتابخانه‌های کلاینت پایتون: کتابخانه‌های کلاینت لازم برای سرویس‌های ابری گوگل را راه‌اندازی کنید.

در نوت‌بوک 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 فرانکفورتر از طریق پروکسی صریح تعریف کنید.

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و پیکربندی زیر را اجرا کنید، به نکات برجسته زیر توجه کنید:

  • تابع def get_exchange_rate از API مربوط به Frankfurter (https://api.frankfurter.app/) برای دریافت داده‌های نرخ ارز استفاده خواهد کرد.
  • proxy_server = "http://proxy-vm.demo.com:8888" FQDN با ماشین مجازی پروکسی مستقر در VPC مصرف‌کننده مرتبط است. ما در مرحله بعدی از DNS peering برای حل FQDN استفاده خواهیم کرد.
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}

استقرار موتور عامل: موتور عامل را مستقر کنید، آن را با رابط PSC و DNS peering پیکربندی کنید تا FQDN ماشین مجازی پروکسی را در VPC مصرف‌کننده حل کنید.

در نوت‌بوک JupyterLab خود، سلول زیر را ایجاد و اجرا کنید، به نکات برجسته زیر توجه کنید:

  • DNS Peering به 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)

نظارت بر وضعیت استقرار: وضعیت عملیات استقرار موتور عامل را بررسی کنید.

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را اجرا کنید.

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

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را اجرا کنید.

توجه: این عملیات می‌تواند حدود ۵ دقیقه طول بکشد. برای بررسی پیشرفت، سلول را دوباره اجرا کنید. لطفاً تا زمانی که خروجی مشابه تصویر زیر را مشاهده نکرده‌اید، به بخش بعدی نروید.

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

نمونه ای از یک اجرای موفق:

3f6dcd1074af7651.png

پرس‌وجو از عامل مستقر: برای آزمایش عملکرد آن، یک پرس‌وجو به موتور عامل مستقر ارسال کنید.

در نوت‌بوک 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)

نتایج پرس‌وجوی استریم: خروجی پرس‌وجوی موتور عامل را استریم می‌کند.

در نوت‌بوک 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))

نمونه ای از یک اجرای موفق:

۱bd81d12426a348f.png

۱۴. اعتبارسنجی 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

۱۵. اعتبارسنجی رابط PSC

همچنین می‌توانید IPهای پیوست شبکه مورد استفاده توسط Agent Engine را با رفتن به مسیر زیر مشاهده کنید:

سرویس‌های شبکه → اتصال سرویس خصوصی → پیوست شبکه → psc-network-attachment

پروژه مستاجر را انتخاب کنید (نام پروژه به -tp ختم می‌شود)

8a4b5a6e5dfd63d7.png

فیلد هایلایت شده، آدرس IP مورد استفاده توسط Agent Engine از پیوست شبکه PSC را نشان می‌دهد.

c618359f6eafc0c6.png

۱۶. اعتبارسنجی ثبت وقایع ابری

از جلسه TCPDump مربوط به proxy-vm خارج شوید و یک 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 Logging بیندازیم تا ببینیم آیا ترافیک مربوط به 104.26.1.198 مشاهده شده است یا خیر.

به مسیر زیر بروید:

مانیتورینگ → کاوشگر لاگ

از فیلتر زیر استفاده کنید:

resource.type="nat_gateway"

۳۱۰۲۴dc29c39084.png

دوره زمانی را انتخاب کنید، سپس پرس و جو را اجرا کنید

5976857e92d149d3.png

ورودی گزارش را که IP عمومی (مقصد) (104.26.1.198) مربوط به api.frankfurter.app و آدرس IP منبع و نام proxy-vm که استفاده از پروکسی صریح برای خروج از اینترنت را تأیید می‌کند، شناسایی می‌کند، گسترش دهید.

14e293a7fea68db4.png

۱۷. تمیز کردن

در نوت‌بوک 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

۱۸. تبریک

تبریک می‌گویم، شما با موفقیت پیکربندی و اعتبارسنجی Agent Engine مستقر شده با رابط اتصال سرویس خصوصی را با خروج اینترنت از طریق یک پروکسی صریح انجام دادید.

شما زیرساخت مصرف‌کننده را ایجاد کردید و یک پیوست شبکه اضافه کردید که به تولیدکننده اجازه می‌داد یک ماشین مجازی چندکاره برای ایجاد پل ارتباطی بین مصرف‌کننده و تولیدکننده ایجاد کند. شما یاد گرفتید که چگونه یک پروکسی صریح و DNS peering ایجاد کنید که امکان اتصال به اینترنت را فراهم می‌کند.

کازموپاپ فکر می‌کند آموزش‌ها فوق‌العاده هستند!!

c911c127bffdee57.jpeg

بعدش چی؟

مطالعه بیشتر و ویدیوها

اسناد مرجع