Agent Engine PSC Explicit Proxy

1. مقدمة

واجهة Private Service Connect هي مورد يتيح لشبكة السحابة الإلكترونية الخاصة الافتراضية (VPC) الخاصة بموفّر الخدمة بدء عمليات ربط بمقاصد مختلفة في شبكة السحابة الإلكترونية الخاصة الافتراضية الخاصة بالمستهلك. يمكن أن تكون شبكات المنتجين والمستهلكين في مشاريع ومؤسسات مختلفة.

إذا قبلت أداة ربط الشبكة اتصالاً من واجهة Private Service Connect، يخصّص Google Cloud للواجهة عنوان IP من شبكة فرعية للمستهلك يحدّدها أداة ربط الشبكة. ترتبط شبكات المستهلكين والمنتجين ويمكنها التواصل باستخدام عناوين IP الداخلية.

يشبه الاتصال بين مرفق الشبكة وواجهة Private Service Connect الاتصال بين نقطة نهاية Private Service Connect ومرفق الخدمة، ولكنّه يختلف عنه في نقطتَين أساسيتَين:

  • تتيح مرفقات الشبكة لشبكة المنتج بدء الاتصالات بشبكة المستهلك (خروج الخدمة المُدارة)، بينما تتيح نقطة النهاية لشبكة المستهلك بدء الاتصالات بشبكة المنتج (دخول الخدمة المُدارة).
  • يكون اتصال واجهة Private Service Connect متعديًا. وهذا يعني أنّه يمكن لشبكة منتِجة التواصل مع شبكات أخرى مرتبطة بشبكة المستهلك.

اعتبارات إمكانية الوصول إلى واجهة PSC في Vertex AI

  • يمكن لواجهة PSC توجيه الزيارات إلى شبكة VPC أو الوجهات المحلية ضمن حظر عناوين RFC1918.
  • يتطلّب استهداف واجهة PSC لكتل العناوين غير RFC-1918 نشر وكيل صريح في شبكة VPC الخاصة بالمستهلك مع عنوان RFC-1918. ضمن عملية نشر Vertex AI، يجب تحديد الخادم الوكيل مع اسم نطاق مؤهَّل بالكامل لنقطة النهاية المستهدَفة.
  • عند ضبط عملية النشر باستخدام واجهة PSC فقط، سيتم الاحتفاظ بإمكانية الوصول التلقائية إلى الإنترنت. تخرج حركة البيانات الصادرة هذه مباشرةً من شبكة المستأجر الآمنة التي تديرها Google.

اعتبارات حول واجهة PSC في Vertex AI مع عناصر التحكّم في سحابة VPC

  • عندما يكون مشروعك جزءًا من حدود "عناصر التحكّم في خدمة السحابة الإلكترونية الافتراضية الخاصة"، يتم حظر الوصول التلقائي إلى الإنترنت للمستأجرين الذين تديرهم Google من خلال الحدود لمنع تسريب البيانات.
  • للسماح بالوصول إلى الإنترنت العام في هذا السيناريو، يجب ضبط مسار خروج آمن يوجّه حركة البيانات من خلال شبكة VPC.
  • الطريقة المقترَحة لتحقيق ذلك هي إعداد خادم وكيل داخل حدود شبكتك الافتراضية الخاصة (VPC) باستخدام عنوان RFC1918 وإنشاء بوابة Cloud NAT للسماح للجهاز الافتراضي الخاص بالوكيل بالوصول إلى الإنترنت.

للحصول على معلومات إضافية، يُرجى الاطّلاع على المراجع التالية:

نشر وكيل | الذكاء الاصطناعي التوليدي على Vertex AI | Google Cloud

إعداد واجهة Private Service Connect لموارد Vertex AI | Google Cloud

ما ستنشئه

في هذا البرنامج التعليمي، ستنشئ Agent Engine شاملة يتم نشرها باستخدام واجهة Private Service Connect (PSC) للسماح بالاتصال بموقع إلكتروني عام (https://api.frankfurter.app/) من خلال آلة افتراضية لخادم وكيل يتم نشرها في السحابة الإلكترونية الافتراضية الخاصة (VPC) للمستهلك باستخدام عنوان RFC1918. ينطبق نموذج النشر على مشروع مفعَّل فيه VPC-SC أو على المشرفين الذين يحتاجون إلى خروج الإنترنت من خلال شبكة العملاء بدلاً من شبكة VPC الخاصة بالمستأجر.

الشكل 1

f42f2db921f6d5af.png

ستنشئ عملية ربط واحدة بين شبكة psc وشبكة VPC الخاصة بالمستهلك، مع الاستفادة من تبادل المعلومات بين نظام أسماء النطاقات (DNS) لحلّ مشكلة الجهاز الظاهري للخادم الوكيل في شبكة المستهلك في مشروع المستأجر الذي يستضيف Agent Engine، ما يؤدي إلى حالات الاستخدام التالية:

نشر Agent Engine وضبط جهاز افتراضي لخادم وكيل ليعمل كخادم وكيل صريح، ما يسمح له بالوصول إلى عنوان URL متاح للجميع https://api.frankfurter.app

ما ستتعلمه

  • كيفية إنشاء مرفق شبكة
  • كيف يمكن لمقدّم الخدمة استخدام مرفق شبكة لإنشاء واجهة PSC؟
  • كيفية إنشاء اتصال من المنتِج إلى المستهلك باستخدام DNS Peering
  • كيفية نشر واستخدام آلة افتراضية وسيطة للخروج من الإنترنت

المتطلبات

مشروع Google Cloud

أذونات "إدارة الهوية وإمكانية الوصول"

2. قبل البدء

تعديل المشروع ليتوافق مع البرنامج التعليمي

يستفيد هذا البرنامج التعليمي من $variables للمساعدة في تنفيذ عملية إعداد gcloud في Cloud Shell.

داخل Cloud Shell، اتّبِع الخطوات التالية:

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

تفعيل واجهة برمجة التطبيقات

داخل 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 list --enabled

3- إعداد المستهلك

إنشاء شبكة VPC للمستهلك

تقع شبكة VPC هذه في مشروع أحد العملاء. سيتم إنشاء الموارد التالية في شبكة VPC هذه

  • الشبكة الفرعية للمستهلك
  • الشبكة الفرعية المرفقة بالشبكة
  • Cloud Router (مطلوب لخدمة Cloud NAT)
  • Cloud NAT

داخل Cloud Shell، اتّبِع الخطوات التالية:

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

إنشاء الشبكات الفرعية للمستهلك

داخل Cloud Shell، أنشئ الشبكة الفرعية للجهاز الظاهري للخادم الوكيل:

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

إنشاء الشبكة الفرعية لمرفق شبكة Private Service Connect

داخل Cloud Shell، أنشئ الشبكة الفرعية لمرفق شبكة PSC:

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

إعداد Cloud Router وNAT

في هذا البرنامج التعليمي، يتم استخدام Cloud NAT لتوفير إمكانية الوصول إلى الإنترنت لجهاز VM الخادم الوكيل الذي لا يتضمّن عنوان IP عامًا. تتيح خدمة Cloud NAT للأجهزة الافتراضية التي تتضمّن عناوين IP خاصة فقط الاتصال بالإنترنت، ما يسمح لها بتنفيذ مهام مثل تثبيت حِزم البرامج.

داخل Cloud Shell، أنشئ Cloud Router.

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

داخل Cloud Shell، أنشئ بوابة NAT مع تفعيل التسجيل. سنستخدم التسجيل للتحقّق من صحة الوصول إلى عنوان IP العام لواجهة Frankfurter API ‏ (https://api.frankfurter.app/).

gcloud compute routers nats create cloud-nat-us-central1 --router=cloud-router-for-nat --auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges --region us-central1 --enable-logging --log-filter=ALL

4. تفعيل عمليات الشراء داخل التطبيق

للسماح لميزة "الوصول إلى الأجهزة الافتراضية عبر الإنترنت" بالاتصال بأجهزة VM الافتراضية، أنشئ قاعدة جدار حماية تتضمّن ما يلي:

  • ينطبق على جميع مثيلات الأجهزة الافتراضية التي تريد إتاحتها باستخدام IAP.
  • تسمح هذه القاعدة بحركة البيانات الواردة من نطاق عناوين IP 35.235.240.0/20. يحتوي هذا النطاق على جميع عناوين IP التي تستخدمها خدمة IAP لإعادة توجيه بروتوكول TCP.

داخل Cloud Shell، أنشئ قاعدة جدار حماية IAP.

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

5- إنشاء مثيلات أجهزة افتراضية للمستهلكين

في Cloud Shell، أنشئ مثيل الجهاز الافتراضي للمستهلك، proxy-vm، الذي سيعمل كخادم وكيل صريح لـ Agent Engine. سنستخدم 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"

6. مرفق شبكة Private Service Connect

مرفقات الشبكة هي موارد إقليمية تمثّل جهة المستهلك في واجهة Private Service Connect. يمكنك ربط شبكة فرعية واحدة بمرفق شبكة، ويحدّد المنتج عناوين IP لواجهة Private Service Connect من تلك الشبكة الفرعية. يجب أن تكون الشبكة الفرعية في المنطقة نفسها التي يتوفّر فيها مرفق الشبكة. يجب أن يكون مرفق الشبكة في المنطقة نفسها التي تتوفّر فيها خدمة المنتج.

إنشاء مرفق الشبكة

داخل Cloud Shell، أنشئ مرفق الشبكة.

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

إدراج مرفقات الشبكة

داخل Cloud Shell، أدرِج مرفق الشبكة.

gcloud compute network-attachments list

وصف مرفقات الشبكة

داخل Cloud Shell، صف مرفق الشبكة.

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

دوِّن اسم مرفق شبكة PSC، psc-network-attachment، الذي سيستخدمه المنتج عند إنشاء واجهة Private Service Connect.

لعرض عنوان URL لملف PSC Network Attachment في Cloud Console، انتقِل إلى ما يلي:

خدمات الشبكة (Network Services) → خدمة Private Service Connect → ربط الشبكة (Network Attachment) → psc-network-attachment

8eec51cb197da218.png

7. منطقة نظام أسماء النطاقات الخاص

ستنشئ منطقة Cloud DNS لـ demo.com وتملأها بسجلّ A يشير إلى عناوين IP الخاصة بـ proxy-vm. في وقت لاحق، سيتم نشر خدمة "تبادل بيانات نظام أسماء النطاقات" في Agent Engine، ما سيسمح بالوصول إلى سجلات نظام أسماء النطاقات الخاصة بالمستهلك.

داخل Cloud Shell، نفِّذ ما يلي لإنشاء عرض توضيحي لاسم نظام أسماء النطاقات 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 الخاصة بالأجهزة الافتراضية المستخدَمة في سجلّات 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" بالوصول إلى الجهاز الظاهري للخادم الوكيل في شبكة VPC الخاصة بالمستهلك.

في Cloud Shell، أنشئ قاعدة جدار الحماية الواردة.

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

8. إنشاء دفتر ملاحظات Jupyter

يرشدك القسم التالي إلى كيفية إنشاء دفتر Jupyter. سيتم استخدام هذا الدفتر لنشر Agent Engine الذي يستهدف خادم وكيل صريحًا للخروج من الإنترنت.

إنشاء حساب خدمة مُدار من قِبل المستخدم

في القسم التالي، ستنشئ حساب خدمة سيتم ربطه بمثيل Vertex AI Workbench المستخدَم في البرنامج التعليمي.

في البرنامج التعليمي، سيتم تطبيق الأدوار التالية على حساب الخدمة:

داخل Cloud Shell، أنشئ حساب الخدمة.

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

داخل Cloud Shell، عدِّل حساب الخدمة باستخدام دور "مشرف التخزين".

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

داخل Cloud Shell، عدِّل حساب الخدمة باستخدام دور "مستخدم Vertex AI".

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

في Cloud Shell، عدِّل حساب الخدمة باستخدام دور "مشرف Artifact Registry".

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

داخل Cloud Shell، اسمح لحساب خدمة دفتر الملاحظات باستخدام حساب خدمة Compute Engine التلقائي.

gcloud iam service-accounts add-iam-policy-binding \
    $(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')-compute@developer.gserviceaccount.com \
    --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" \
    --role="roles/iam.serviceAccountUser"

9- تعديل الخادم الوكيل الصريح

في القسم التالي، عليك استخدام ssh للدخول إلى الخادم الوكيل الصريح وتعديل ملف الإعداد tinyproxy.conf، ثم إعادة الضبط.

من Cloud Shell

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

افتح ملف إعدادات tinyproxy، وعدِّله باستخدام محرِّر من اختيارك. في ما يلي مثال على استخدام VIM.

sudo vim /etc/tinyproxy/tinyproxy.conf

# Locate the "Listen" configuration line to restrict listening to only its private IP address of the Proxy-VM, rather than all interfaces. 

Listen 10.10.10.2

# Locate the "Allow" configuration line to allow requests ONLY from the PSC Network Attachment Subnet

Allow 192.168.10.0/24

Save the configs by the following steps:
1. Press the `ESC` key to enter Command Mode.
2. Type `:wq` to save (w) and quit (q).
3. Press `Enter`

Restart the tinyproxy service to apply the changes:
sudo systemctl restart tinyproxy

Validate the tinyproxy service is running:
sudo systemctl status tinyproxy

Perform an exit returning to cloud shell
exit

10. إنشاء مثيل Vertex AI Workbench

في القسم التالي، أنشئ مثيلاً من Vertex AI Workbench يتضمّن حساب الخدمة الذي تم إنشاؤه سابقًا، notebook-sa.

داخل Cloud Shell، أنشئ مثيل العميل الخاص.

gcloud workbench instances create workbench-tutorial --vm-image-project=cloud-notebooks-managed --vm-image-family=workbench-instances --machine-type=n1-standard-4 --location=us-central1-a --subnet-region=us-central1 --subnet=rfc1918-subnet1 --disable-public-ip --shielded-secure-boot=true --shielded-integrity-monitoring=true --shielded-vtpm=true --service-account-email=notebook-sa@$projectid.iam.gserviceaccount.com

11. تعديل وكيل خدمة Vertex AI

تتولّى Vertex AI نيابةً عنك تنفيذ عمليات، مثل الحصول على عنوان IP من الشبكة الفرعية لمرفق شبكة PSC المستخدَمة لإنشاء واجهة PSC. لإجراء ذلك، تستخدم Vertex AI وكيل خدمة (مدرَج أدناه) يتطلّب إذن مشرف الشبكة:

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

داخل Cloud Shell، احصل على رقم مشروعك.

gcloud projects describe $projectid | grep projectNumber

داخل Cloud Shell، اضبط رقم مشروعك.

projectnumber=YOUR-PROJECT-Number

داخل Cloud Shell، أنشئ حساب خدمة لمنصة AI Platform. تخطَّ هذه الخطوة إذا كان لديك حساب خدمة حالي في مشروعك.

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

داخل Cloud Shell، عدِّل حساب وكيل الخدمة باستخدام الدور compute.networkAdmin.

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

داخل Cloud Shell، عدِّل حساب وكيل الخدمة باستخدام الدور dns.peer

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

تعديل حساب الخدمة التلقائي

امنح حساب الخدمة التلقائي إذن الوصول إلى Vertex AI. يُرجى العِلم أنّ نشر التغيير في إذن الوصول قد يستغرق بعض الوقت.

داخل Cloud Shell، عدِّل حساب الخدمة التلقائي باستخدام الدور aiplatform.user

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

12. Proxy VM Tcpdump

للتحقّق من صحة اتصال IP من Agent Engine، يمكننا استخدام TCPDUMP. سيسمح لنا ذلك بمراقبة الاتصال الوارد من الشبكة الفرعية "مرفق شبكة PSC"، 192.168.10.0/28 عند استدعاء طلب get من Agent Engine إلى عنوان URL العام.

من Cloud Shell، يمكنك استخدام ssh للوصول إلى الجهاز الظاهري للخادم الوكيل.

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

نفِّذ tcpdump من نظام التشغيل proxy-vm.

sudo tcpdump -i any net 192.168.10.0/28 -nn

13. نشر "محرك الوكيل"

ملاحظة: سنستخدم وحدة تحكّم GCP ودفتر ملاحظات JupyterLab لإكمال المهام في هذا القسم.

في القسم التالي، ستنشئ دفتر ملاحظات ينفّذ المهام التالية:

  • يستخدم واجهة برمجة التطبيقات Frankfurter API (https://api.frankfurter.app/) للحصول على بيانات أسعار الصرف
  • تشير إلى خادم وكيل صريح (proxy_server) يستهدف الجهاز الوكيل (proxy-vm) في شبكة VPC الخاصة بالمستهلكين باستخدام اسم النطاق المؤهّل بالكامل proxy-vm.demo.com
  • تحديد dnsPeeringConfigs "domain": "demo.com."

نفِّذ مهمة التدريب في مثيل Vertex AI Workbench.

  • في Google Cloud Console، انتقِل إلى Vertex AI → Workbench
  • بجانب اسم مثيل Vertex AI Workbench (workbench-tutorial)، انقر على "فتح JupyterLab". سيتم فتح مثيل Vertex AI Workbench في JupyterLab.
  • انقر على "ملف" > "جديد" > "دفتر ملاحظات".
  • اختَر Kernel > Python 3

تثبيت مكتبات Python اللازمة: ثبِّت المكتبات المطلوبة لـ Agent Engine، بما في ذلك pyyaml وgoogle-cloud-aiplatform وcloudpickle وgoogle-cloud-api-keys وlangchain-google-vertexai.

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

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

أعِد تشغيل نواة Jupyter Notebook: تأكَّد من تحميل المكتبات المثبَّتة حديثًا بشكلٍ صحيح.

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

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

import IPython

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

ضبط متغيّرات المشروع والحزمة: حدِّد رقم تعريف مشروع Google Cloud ورقم المشروع واسم الخدمة ودليل GCS ونقطة النهاية واسم الحزمة والموقع الجغرافي.

عدِّل الحقول التالية قبل تنفيذ الخلية

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

ملاحظة: سنستخدم المتغيّر BUCKET لإنشاء حزمة Cloud Storage في الخطوة التالية.

في مفكرة 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: أنشئ حزمة Cloud Storage لتخزين رمز الوكيل.

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

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

تحديد اسم مرفق الشبكة: حدِّد اسم مرفق شبكة Private Service Connect.

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

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

تهيئة مكتبات برامج Python: إعداد مكتبات البرامج اللازمة لخدمات Google Cloud

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

import json
import pprint

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


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

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

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


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

إعداد الوكيل والأدوات: حدِّد فئة StreamingAgent ووظيفة get_exchange_rate لاسترجاع أسعار صرف العملات باستخدام واجهة Frankfurter API من خلال الوكيل الصريح.

في مفكرة JupyterLab، أنشئ خلية جديدة وشغِّل الإعدادات أدناه، مع ملاحظة النقاط البارزة التالية:

  • ستستخدم الدالة def get_exchange_rate واجهة Frankfurter API (https://api.frankfurter.app/) للحصول على بيانات سعر الصرف.
  • proxy_server = "http://proxy-vm.demo.com:8888" يتم ربط اسم النطاق المؤهّل بالكامل (FQDN) بالجهاز الظاهري للخادم الوكيل الذي تم نشره في شبكة VPC الخاصة بالمستهلك. نستخدم ربط نظام أسماء النطاقات لتحديد اسم النطاق المؤهّل بالكامل في خطوة لاحقة.
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()

تحميل ملفات الوكيل إلى Cloud Storage: حمِّل الوكيل المتسلسل ومتطلباته إلى حزمة GCS المحدّدة.

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي:

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

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


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

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

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

نشر Agent Engine: يمكنك نشر Agent Engine وإعداده باستخدام واجهة PSC ونظير DNS لحلّ اسم النطاق المؤهّل بالكامل (FQDN) الخاص بالجهاز الظاهري للخادم الوكيل في شبكة VPC الخاصة بالمستهلك.

في دفتر ملاحظات JupyterLab، أنشئ الخلية أدناه وشغِّلها، مع ملاحظة النقاط البارزة التالية:

  • يتم ضبط ميزة "نظير نظام أسماء النطاقات" (DNS) مع شبكات VPC الخاصة بالمستهلكين باستخدام dnsPeeringConfigs (dnsPeeringConfigs) لاسم النطاق demo.com.
import requests


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

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

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

مراقبة حالة النشر: تحقَّق من حالة عملية نشر Agent Engine.

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

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

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

ملاحظة: قد تستغرق هذه العملية حوالي 5 دقائق حتى تكتمل. أعِد تشغيل الخلية للتحقّق من مدى التقدّم. يُرجى عدم الانتقال إلى القسم التالي إلى أن يظهر لك ناتج مشابه للقطة الشاشة أدناه.

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

مثال على عملية تنفيذ ناجحة:

3f6dcd1074af7651.png

طلب البحث من الوكيل الذي تم نشره: أرسِل طلب بحث إلى Agent Engine الذي تم نشره لاختبار وظائفه.

في دفتر JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي.

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

بث نتائج طلب البحث: بث النتائج من طلب بحث Agent Engine

في دفتر ملاحظات JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي الذي سيؤدي إلى تشغيل طلب البيانات من واجهة برمجة التطبيقات إلى عنوان 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))

مثال على عملية تنفيذ ناجحة:

1bd81d12426a348f.png

14. التحقّق من صحة Tcpdump

عرض مخرجات tcpdump التي توضّح بالتفصيل عملية التواصل بين عنوان IP المرفق بشبكة PSC الذي يستخدمه Agent Engine وProx-VM عند نشر الطلب

user@proxy-vm:~$ sudo tcpdump -i any net 192.168.10.0/28 -nn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
22:17:53.983212 ens4  In  IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [S], seq 3841740961, win 28800, options [mss 1440,sackOK,TS val 4245243253 ecr 0,nop,wscale 7], length 0
22:17:53.983252 ens4  Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [S.], seq 2232973833, ack 3841740962, win 64768, options [mss 1420,sackOK,TS val 2251247643 ecr 4245243253,nop,wscale 7], length 0
22:17:53.985167 ens4  In  IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [.], ack 1, win 225, options [nop,nop,TS val 4245243256 ecr 2251247643], length 0
22:17:53.986476 ens4  In  IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [P.], seq 1:45, ack 1, win 16384, options [nop,nop,TS val 4245243256 ecr 2251247643], length 44
22:17:53.986485 ens4  Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [.], ack 45, win 506, options [nop,nop,TS val 2251247646 ecr 4245243256], length 0
22:17:54.043347 ens4  Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [P.], seq 1:71, ack 45, win 506, options [nop,nop,TS val 2251247703 ecr 4245243256], length 70

15. التحقّق من صحة واجهة PSC

يمكنك أيضًا الاطّلاع على عناوين IP المرفقة بالشبكة التي يستخدمها Agent Engine من خلال الانتقال إلى ما يلي:

خدمات الشبكة (Network Services) → خدمة Private Service Connect → ربط الشبكة (Network Attachment) → psc-network-attachment

اختَر مشروع المستأجر (اسم المشروع الذي ينتهي بـ ‎-tp)

8a4b5a6e5dfd63d7.png

يشير الحقل المميّز إلى عنوان IP الذي يستخدمه Agent Engine من "ملحق شبكة PSC".

c618359f6eafc0c6.png

16. التحقّق من صحة Cloud Logging

اخرج من جلسة 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 لمعرفة ما إذا تم رصد زيارات للعنوان 104.26.1.198.

انتقِل إلى ما يلي:

المراقبة → مستكشف السجلات

استخدِم الفلتر التالي:

resource.type="nat_gateway"

31024dc29c39084.png

اختَر الفترة الزمنية، ثم انقر على "تنفيذ الاستعلام"

5976857e92d149d3.png

وسِّع إدخال السجلّ الذي يحدّد عنوان IP المتاح للجميع (الوجهة) (104.26.1.198) الخاص بـ api.frankfurter.app وعنوان IP المصدر واسم proxy-vm الذي يتحقّق من صحة استخدام الخادم الوكيل الصريح للخروج من الإنترنت.

14e293a7fea68db4.png

17. تَنظيم

في مفكرة JupyterLab، أنشئ خلية جديدة وشغِّل ما يلي الذي سيؤدي إلى حذف عملية نشر Agent Engine.

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

response = requests.delete(
    f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/us-central1/reasoningEngines/{reasoning_engine_id}",
    headers={
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": f"Bearer {token[0]}"
    },
)
print(response.text)

من Cloud Shell، احذف مكوّنات البرنامج التعليمي.

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

gcloud dns managed-zones delete private-dns-codelab

gcloud compute instances delete proxy-vm --zone=us-central1-a --quiet

gcloud compute instances delete workbench-tutorial --zone=us-central1-a --quiet

gcloud compute routers delete cloud-router-for-nat --region=us-central1 --quiet

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

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

gcloud compute networks delete consumer-vpc --quiet

18 تهانينا

تهانينا، لقد نجحت في إعداد Agent Engine والتحقّق من صحته، وتم نشر Agent Engine باستخدام واجهة Private Service Connect مع إمكانية الخروج من الإنترنت من خلال وكيل صريح.

لقد أنشأت البنية الأساسية للمستهلك، وأضفت مرفق شبكة سمح للمنتج بإنشاء جهاز افتراضي متعدد بطاقات واجهة شبكة (NIC) لربط الاتصال بين المستهلك والمنتج. تعرّفت على كيفية إنشاء وكيل صريح وإعداد نظير لنظام أسماء النطاقات (DNS) يتيح الاتصال بالإنترنت.

تعتقد Cosmopup أنّ الفيديوهات التعليمية رائعة!!

c911c127bffdee57.jpeg

ما هي الخطوات التالية؟

مزيد من القراءة والفيديوهات

المستندات المرجعية