یکپارچه‌سازی PSC SWP با موتور عامل (ADK)

۱. مقدمه

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

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

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

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

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

  • رابط PSC قادر به مسیریابی ترافیک به VPC یا مقصدهای مبتنی بر درون سازمانی است که توسط شبکه VPC آموخته شده‌اند.
  • برای محدود کردن دامنه دسترسی از اتصال شبکه‌ای که توسط Agent Engine به شبکه VPC استفاده می‌شود، پیاده‌سازی قوانین فایروال خروجی بهترین روش است.
  • برای محدود کردن دامنه ترافیک خروجی شبکه که از زیرشبکه اتصال شبکه Agent Engine سرچشمه می‌گیرد، باید یک قانون فایروال خروجی VPC مستقر شود. این قانون صراحتاً ترافیک از Agent Engine به SWP را مجاز می‌داند، در حالی که سایر ترافیک‌های خروجی را مسدود می‌کند.

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

  • برای اینکه رابط PSC موتور عامل بتواند کار کند، حتی اگر کنترل‌های سرویس VPC فعال باشند، شما باید اتصال خروجی اینترنت را در VPC مشتری فراهم کنید.

پروکسی وب امن

پروکسی وب امن ، یک سرویس مدیریت‌شده و مبتنی بر ابر است که به شما کنترل و امنیت دقیقی برای ترافیک خروجی (HTTP/HTTPS) ارائه می‌دهد. این سرویس به عنوان یک دروازه مرکزی عمل می‌کند و به شما امکان می‌دهد سیاست‌های امنیتی را روی اتصالات آغاز شده از Agent Engine مستقر با رابط PSC به منابع VPC، مانند ماشین‌های مجازی، GKE، اینترنت و محیط‌های چند ابری، اعمال کنید.

چه چیزی را حل می‌کند؟

  • جلوگیری از خروج داده‌ها: آپلودهای غیرمجاز یا ارتباط با سایت‌های مخرب را مسدود می‌کند.
  • اجرای قوانین: تضمین می‌کند که ترافیک خروجی با سیاست‌های امنیتی و مدیریت داده‌های سازمان شما مطابقت دارد.
  • کاهش سربار عملیاتی: به عنوان یک سرویس کاملاً مدیریت‌شده، Secure Web Proxy نیاز به استقرار، مقیاس‌بندی یا نگهداری ماشین‌های مجازی پروکسی شخصی شما را از بین می‌برد.
  • قابلیت دید عمیق را فراهم می‌کند: امکان بازرسی ترافیک رمزگذاری شده توسط امنیت لایه انتقال (TLS) را برای شناسایی تهدیدات پنهان فراهم می‌کند.

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

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

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

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

در این آموزش، شما قصد دارید یک موتور عامل جامع مستقر با رابط سرویس خصوصی (PSC) یکپارچه با SWP بسازید تا موارد زیر را با استفاده از کتابخانه‌های ADK انجام دهد:

  • برای حل مشکل SWPهای Fully Qualified Domain Name که در پیکربندی پروکسی استفاده شده‌اند، DNS peering را در Agent Engine مستقر کنید.
  • امکان اتصال به یک سایت عمومی (https://api.frankfurter.app/) از طریق یک پروکسی وب امن که در VPC مصرف‌کننده با آدرس RFC1918 مستقر شده است را فراهم کنید.
  • اجازه دهید ترافیک از زیرشبکه پیوست شبکه به SWP برسد و سایر ترافیک‌ها رد شوند.

شکل ۱

565e9eb07ef18f44.png

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

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

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

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

مجوزهای IAM

۲. قبل از شروع

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

این آموزش از متغیرها (variables) برای کمک به پیاده‌سازی پیکربندی gcloud در Cloud Shell استفاده می‌کند.

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

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

تأیید کنید که APIها با موفقیت فعال شده‌اند

gcloud services list --enabled

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

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

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

  • زیرشبکه مصرف‌کننده
  • زیرشبکه پیوست شبکه
  • زیرشبکه فقط پروکسی
  • قوانین فایروال
  • DNS ابری

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

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

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

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

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

زیرشبکه اتصال شبکه خصوصی (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 --enable-private-ip-google-access

ایجاد زیرشبکه پروکسی منطقه‌ای

در داخل Cloud Shell، زیرشبکه فقط پروکسی مورد نیاز برای محصولات مبتنی بر Envoy مانند Secure Web Proxy و متعادل‌کننده‌های بار برنامه داخلی/خارجی منطقه‌ای را ایجاد کنید. پرچم –purpose باید روی REGIONAL_MANAGED_PROXY تنظیم شود:

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

زیرشبکه نوت‌بوک را ایجاد کنید

درون Cloud Shell، زیرشبکه را برای نمونه نوت‌بوک ایجاد کنید:

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

۴. ایجاد پروکسی وب امن

حالت صریح پروکسی وب امن (یا حالت مسیریابی پروکسی صریح) یک روش استقرار است که در آن بارهای کاری کلاینت باید به صراحت پیکربندی شوند تا از آدرس IP داخلی SWP یا نام دامنه کاملاً واجد شرایط و پورت به عنوان پروکسی ارسال خود استفاده کنند.

این خط‌مشی شامل قوانینی خواهد بود که ترافیک را از طریق پروکسی وب امن بر اساس تطابق جلسه، host() == 'api.frankfurter.app' و application match request.method == 'GET' کنترل می‌کنند.

در مراحل زیر، مطمئن شوید که YOUR-PROJECT-ID به Project ID خود تغییر می‌دهید.

درون Cloud Shell، یک فایل policy.yaml ایجاد کنید:

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

درون Cloud Shell، پالیسی را وارد کنید:

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

ایجاد قوانین پروکسی وب امن

قوانینی را در داخل پالیسی تعریف کنید تا مشخص شود چه ترافیکی مجاز یا غیرمجاز است. قوانین بر اساس اولویت ارزیابی می‌شوند.

درون Cloud Shell، یک فایل rule.yaml ایجاد کنید تا امکان دسترسی به نقطه پایانی اینترنت مورد استفاده موتور عامل، api.frankfurter.app، فراهم شود:

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

در Cloud Shell، قانون سیاست امنیتی ایجاد کنید:

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

ایجاد قوانین پروکسی وب امن

نمونه SWP که در حالت مسیریابی صریح مستقر شده است، باید طوری ایجاد شود که موتور عامل (Agent Engine) ملزم به مشخص کردن آدرس IP یا FQDN مربوط به SWP در پیکربندی پروکسی ADK، همانطور که در فایل YAML دروازه تعریف شده است، باشد. این پیکربندی همچنین نمونه را به سیاست، شبکه و زیرشبکه مربوطه پیوند می‌دهد.

درون Cloud Shell، یک فایل gateway.yaml ایجاد کنید که برای استقرار SWP استفاده می‌شود.

حتماً فایل YAML را پس از به‌روزرسانی متغیرهای زیر با جزئیات محیط خود ذخیره کنید: PROJECT_ID، REGION، NETWORK_NAME و PROXY_ONLY_SUBNET_NAME. پورت ۸۸۸۸ مشخص شده، پورت تونل بیرونی است که به پیکربندی پروکسی در Agent Engine نگاشت شده است.

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

درون Cloud Shell، گیت‌وی را وارد کنید:

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

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

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

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

۱۵f۸۰b۴۶c۳a۰۳۳۲d.png

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

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

درون Cloud Shell، یک توصیف روی swp، my-swp-instance، انجام دهید:

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

درون Cloud Shell، رکوردهای تنظیم‌شده برای SWP، swp.demo.com، را ایجاد کنید و مطمئن شوید که آدرس IP را بر اساس خروجی محیط خود به‌روزرسانی می‌کنید.

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

پیکربندی فایروال

یک قانون فایروال ابری ایجاد کنید تا دسترسی از رابط PSC امکان‌پذیر باشد

در بخش بعدی، یک قانون فایروال ایجاد کنید که به ترافیک ناشی از PSC Network Attachment اجازه دسترسی به زیرشبکه SWP در Consumer VPC را بدهد. برای افزایش امنیت، می‌توانید آدرس IP SWP را به عنوان تنها مقصد مشخص کنید.

در Cloud Shell، قانون فایروال خروجی را ایجاد کنید که امکان دسترسی از طریق اتصال شبکه به SWP را فراهم کند:

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

در Cloud Shell، یک قانون فایروال خروجی ایجاد کنید که تمام ترافیک از پیوست شبکه را مسدود کند:

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

۷. برای اطمینان از هوش تهدید، یک سیاست فایروال برای شبکه VPC ایجاد کنید:

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

در Cloud Shell، سیاست فایروال سراسری را ایجاد کنید:

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

در Cloud Shell، این Policy را با VPC خود مرتبط کنید:

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

در Cloud Shell، قوانین هوش تهدید را اضافه کنید:

این قوانین، ترافیک مربوط به عوامل مخرب شناخته‌شده را قبل از شروع ترافیک از Agent، کاهش می‌دهند. در این مثال، ما قوانینی را برای مسدود کردن گره‌های خروجی Tor (Egress) و مسدود کردن IPهای مخرب شناخته‌شده (Egress)، مسدود کردن پروکسی‌های ناشناس شناخته‌شده (Egress)، مسدود کردن استخراج‌کنندگان ارز دیجیتال برای جلوگیری از استفاده غیرمجاز از منابع (Egress) اضافه کرده‌ایم.

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

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

بخش بعدی شما را در ایجاد یک 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"

۹. یک نمونه از میز کار 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=notebook-subnet --disable-public-ip --shielded-secure-boot=true --shielded-integrity-monitoring=true --shielded-vtpm=true --service-account-email=notebook-sa@$projectid.iam.gserviceaccount.com     

یک قانون دیگر در Secure Web Proxy موجود اضافه کنید تا ترافیک را از این نمونه نوت‌بوک هدایت کند:

در Cloud Shell، فایل rule-notebook.yaml را با استفاده از یک ویرایشگر متن ایجاد کنید، مطمئن شوید که YAML را با شناسه پروژه خود به‌روزرسانی می‌کنید.

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

در Cloud Shell، قانون سیاست امنیتی ایجاد کنید:

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

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

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"

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

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

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

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

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

  • در کنسول گوگل کلود، به مسیر Vertex AI → Workbench بروید.
  • در کنار نام نمونه Vertex AI Workbench خود (workbench-tutorial)، روی Open JupyterLab کلیک کنید. نمونه Vertex AI Workbench شما در JupyterLab باز می‌شود.
  • File > New > Notebook را انتخاب کنید
  • Kernel > Python 3 را انتخاب کنید

نصب کتابخانه‌های پایتون لازم: کتابخانه‌های مورد نیاز برای Agent Engine، از جمله pyyaml، google-cloud-aiplatform، cloudpickle، google-cloud-api-keys و langchain-google-vertexai را نصب کنید.

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را با مشخص کردن آدرس IP SWPs اجرا کنید:

7b827a6a38bb5afc.png

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

متغیرهای زیر را بر اساس محیط خود در قطعه کد زیر تعریف کنید:

  • شناسه پروژه
  • نام سطل
  • نام نماینده

در این آزمایش، شما از متغیرهای BUCKET_NAME و AGENT_NAME برای مقداردهی اولیه و پیکربندی سطل ذخیره‌سازی خود که به صورت سراسری در دسترس است، استفاده خواهید کرد.

در بخش بعدی، PROXY_SERVER تعریف شده است، مثلاً swp.demo.com که برای تبدیل نام به DNS peering نیاز دارد. در پیکربندی، AGENT_PEER_DOMAIN به صورت demo.com مستقر می‌شود که مربوط به منطقه DNS خصوصی ایجاد شده در مرحله قبلی در AGENT_PEER_NETWORK، consumer-vpc است.

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

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

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

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

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

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

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

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

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

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

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را برای ایجاد متغیر پروکسی که مربوط به FQDN و پورت SWPها است، اجرا کنید.

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

کد زیر پیکربندی صریح پروکسی را برای Agent Engine جهت دسترسی به نقطه پایانی اینترنت api.frankfurter.app با مشخص کردن SWP، با استفاده از PROXY_SERVER_TO_USE که به os.environ["PROXY_SERVER_URL"].

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

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و کد زیر را که پیاده‌سازی ابزار برای هدف‌گیری تبادل ارز api.frankfurther.app را تعریف می‌کند، اجرا کنید.

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


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

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

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

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

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

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

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

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

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

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را اجرا کنید که علاوه بر اتصال DNS، پیکربندی رابط psc مورد استفاده توسط Agent Engine را نیز فراخوانی می‌کند.

import json
import os

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

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

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

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

import json
import os

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

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

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

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

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

%%writefile $AGENT_NAME/.env

GOOGLE_CLOUD_PROJECT=PROJECT_ID
GOOGLE_CLOUD_LOCATION=us-central1
GOOGLE_GENAI_USE_VERTEXAI=1


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

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را که عامل (Agent) را ایجاد می‌کند، اجرا کنید.

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

یک شناسه موتور استدلال (reasoning engine ID) پس از اجرای سلول ایجاد می‌شود. برای مرحله بعدی، به شناسه تولید شده نیاز دارید که در این مثال 3235268984265768960 است.

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

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را اجرا کنید، و مطمئن شوید که با شماره پروژه و شناسه استدلال موتور عامل خود از خروجی قبلی به‌روزرسانی می‌کنید:

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

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

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

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

        part = parts[0] # Get the first part

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

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

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

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

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

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

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

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



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

نمونه‌ای از اجرای موفق که اتصال به نقطه پایانی عمومی api.frankfurther.app را از طریق SWP بر اساس نرخ تبدیل USD به INR تأیید می‌کند.

f9f925983ab5cc9d.png

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

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

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

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

c9c412334a7f5ad9.png

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

e94c6c03fb51f7fe.png

۱۳. SWP - اعتبارسنجی ثبت وقایع ابری

برای مشاهده‌ی Cloud Logging جهت اعتبارسنجی خروج اینترنتی انجام شده توسط SWP، به مسیر زیر بروید:

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

عبارت زیر را وارد کنید: resource.type=" networkservices.googleapis.com/Gatewa y" و سپس روی اجرای عبارت کلیک کنید. در زیر مثالی آمده است که نقطه پایانی مقصد، api.frankfurter.app، را تأیید می‌کند.

f53831ef8ec663db.png

fc154a5b22da2a87.png

مثال ثبت وقایع ابری زیر، موارد زیر را تأیید می‌کند:

محدوده مقصد: آدرس IP رابط PSC موتور عامل

Source_range: فقط پروکسی زیرشبکه Dest_ip: آدرس IP پروکسی وب امن

مطمئن شوید که project_id برای کوئری ثبت وقایع ابری تغییر می‌دهید.

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

۱۴. تمیز کردن

در نوت‌بوک JupyterLab خود، یک سلول جدید ایجاد کنید و دستور زیر را اجرا کنید که باعث حذف استقرار Agent Engine می‌شود.

مطمئن شوید که "project number" و "reasoningEngines token" را به‌روزرسانی می‌کنید.

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

از Cloud Shell، اجزای آموزشی را حذف کنید.

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

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

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

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

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

gcloud dns managed-zones delete private-dns-codelab


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

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


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

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

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

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

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

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

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

gcloud compute networks delete consumer-vpc --quiet

۱۵. تبریک

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

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

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

e6d3675ca7c6911f.jpeg

بعدش چی؟

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

اسناد مرجع