دمج Agent Engine (ADK) PSC SWP

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-Interface توجيه الزيارات إلى شبكة VPC أو إلى وجهات محلية تعرّفت عليها شبكة VPC.
  • للحدّ من نطاق إمكانية الوصول من مرفق الشبكة الذي يستخدمه Agent Engine إلى شبكة VPC، يُعدّ تنفيذ قواعد جدار الحماية الصادرة أفضل ممارسة.
  • للحدّ من نطاق الزيارات الخارجة من الشبكة والواردة من الشبكة الفرعية المرفقة بشبكة Agent Engine، يجب نشر قاعدة جدار حماية خارجية لشبكة VPC. ستسمح هذه القاعدة صراحةً بحركة البيانات من Agent Engine إلى SWP، مع رفض جميع حركات البيانات الصادرة الأخرى.

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

  • يجب توفير اتصال بحركة البيانات الصادرة من الإنترنت داخل شبكة VPC الخاصة بالعميل لكي تعمل واجهة PSC الخاصة بـ Agent Engine، حتى في حال تفعيل عناصر التحكّم في خدمة VPC.

الخادم الوكيل الآمن للويب

Secure Web Proxy هي خدمة مُدارة ومصمّمة خصيصًا للعمل على السحابة الإلكترونية، وتمنحك إمكانية التحكّم الدقيق في حركة المرور الصادرة (HTTP/HTTPS) وتوفّر لها الأمان. يعمل كبوابة مركزية، ما يتيح لك فرض سياسات الأمان على الاتصالات التي يتم بدؤها من Agent Engine الذي تم نشره باستخدام واجهة PSC إلى موارد شبكة VPC، مثل الأجهزة الافتراضية وGKE والإنترنت وبيئات السحابة الإلكترونية المتعددة.

المشاكل التي يحلّها

  • منع استخراج البيانات: يتم حظر عمليات التحميل غير المصرَّح بها أو التواصل مع المواقع الإلكترونية الضارة.
  • فرض الامتثال: يضمن الالتزام بسياسات الأمان وسياسة التعامل مع البيانات في مؤسستك عند نقل البيانات إلى خارج المؤسسة.
  • تقليل النفقات التشغيلية: بصفتها خدمة مُدارة بالكامل، تلغي خدمة Secure Web Proxy الحاجة إلى نشر أو توسيع أو صيانة الأجهزة الافتراضية الخاصة بالخادم الوكيل.
  • توفير إمكانية رصد دقيق: تتيح فحص الزيارات المشفّرة باستخدام بروتوكول أمان طبقة النقل (TLS) لرصد التهديدات المخفية.

لمزيد من المعلومات، يُرجى الاطّلاع على المراجع التالية:

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

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

ما ستنشئه

في هذا البرنامج التعليمي، ستنشئ "محرك وكيل" شاملاً تم تفعيله باستخدام واجهة Private Service Connect (PSC) المدمجة مع SWP لتنفيذ ما يلي باستخدام مكتبات ADK:

  • يمكنك نشر ربط نظام أسماء النطاقات في Agent Engine لحلّ اسم النطاق المؤهّل بالكامل (FQDN) الخاص بـ SWP والمستخدَم في إعدادات الخادم الوكيل.
  • السماح بإمكانية الاتصال بموقع إلكتروني عام (https://api.frankfurter.app/) من خلال خادم وكيل آمن على الويب تم تفعيله في شبكة VPC الخاصة بالمستهلك باستخدام عنوان RFC1918
  • السماح بتلقّي الزيارات من الشبكة الفرعية المرفقة بالشبكة إلى SWP مع رفض أي شيء آخر

الشكل 1

565e9eb07ef18f44.png

ما ستتعلمه

  • كيفية إنشاء مرفق شبكة
  • كيف يمكن للمنتج استخدام مرفق شبكة لإنشاء واجهة PSC؟
  • كيفية إنشاء اتصال من المنتِج إلى المستهلك باستخدام DNS Peering
  • كيفية نشر واستخدام SWP للخروج من الإنترنت
  • كيفية تحديد قواعد جدار الحماية الصادر لتقليل إمكانية الوصول إلى شبكة Agent Engine

المتطلبات

مشروع Google Cloud

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

2. قبل البدء

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

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

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

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

التأكّد من تفعيل واجهات برمجة التطبيقات بنجاح

gcloud services list --enabled

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

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

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

  • شبكة المستهلك الفرعية
  • الشبكة الفرعية المرفقة بالشبكة
  • الشبكة الفرعية للخادم الوكيل فقط
  • قواعد جدار الحماية
  • Cloud 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

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

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

4. إنشاء خادم وكيل آمن للويب

"الوضع الصريح" (أو "وضع توجيه الخادم الوكيل الصريح") في Secure Web Proxy هو طريقة نشر يجب فيها ضبط أحمال عمل العميل بشكل صريح لاستخدام عنوان IP الداخلي أو اسم النطاق المؤهَّل بالكامل والمنفذ في SWP كخادم وكيل لإعادة التوجيه.

ستتضمّن هذه السياسة القواعد التي تحكم حركة البيانات من خلال وكيل الويب الآمن استنادًا إلى تطابق الجلسة host() == 'api.frankfurter.app' وتطابق التطبيق request.method == 'GET'.

في الخطوات أدناه، احرص على تعديل YOUR-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. المنفذ 8888 المحدّد هو منفذ الاتصال النفقي الخارجي الذي تم ربطه بإعدادات الخادم الوكيل في 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

5- مرفق شبكة 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

15f80b46c3a0332d.png

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

عليك إنشاء منطقة Cloud DNS لـ demo.com وملؤها بسجلّ A يشير إلى عناوين IP الخاصة بمواقع الويب المحمية. في وقت لاحق، سيتم تفعيل خدمة تبادل معلومات بين الشبكات لنظام أسماء النطاقات في 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 الخاصة بـ SWP المستخدمة في سجلّ 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"

إعدادات جدار الحماية

إنشاء قاعدة Cloud Firewall للسماح بالوصول من واجهة PSC

في القسم التالي، أنشئ قاعدة جدار حماية تسمح بزيارات مصدرها الوصول إلى "مرفق شبكة" في PSC، وذلك إلى الشبكة الفرعية SWP في شبكة 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

7. أنشئ سياسة جدار حماية لشبكة VPC لضمان "معلومات التهديدات":

في القسم التالي، أنشئ سياسة جدار حماية تتيح لك الاستفادة من قوائم التهديدات المُدارة من Google لحظر المواقع الإلكترونية الضارة المعروفة قبل أن تتلقّى SWP الزيارات.

في Cloud Shell، أنشئ سياسة جدار الحماية العامة:

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

في Cloud Shell، اربط السياسة بشبكة 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، أضِف "قواعد معلومات التهديدات" (Threat Intelligence Rules):

ستؤدي هذه القواعد إلى حظر الزيارات الواردة من الجهات الضارة المعروفة قبل بدء الزيارات من "الوكيل". في هذا المثال، أضفنا قواعد إلى "حظر عقد خروج Tor" (الخروج) و"حظر عناوين IP الضارة المعروفة" (الخروج) و"حظر الخوادم الوكيلة المجهولة المعروفة" (الخروج) و"حظر برامج تعدين العملات المشفّرة" لمنع الاستخدام غير المصرّح به للموارد (الخروج).

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

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

يرشدك القسم التالي إلى كيفية إنشاء دفتر ملاحظات Jupyter. سيتم استخدام هذا الدفتر لتفعيل "محرك الوكيل" الذي يستهدف خادم وكيل صريحًا لحركة البيانات الصادرة من الإنترنت.

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

في القسم التالي، ستنشئ حساب خدمة سيتم ربطه بمثيل 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- إنشاء مثيل 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=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

10. تعديل وكيل خدمة 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"

11. تفعيل محرك الوكيل

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

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

  • يستخدم واجهة برمجة التطبيقات Frankfurter API (https://api.frankfurter.app/) للحصول على بيانات أسعار الصرف
  • تشير إلى خادم وكيل صريح (proxy_server) يستهدف SWP في شبكة VPC الخاصة بالمستهلكين باستخدام اسم المجال المؤهّل بالكامل swp.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.
  • اختيار File > New > Notebook
  • اختيار Kernel > Python 3

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

في دفتر ملاحظات JupyterLab، أنشئ خلية جديدة ونفِّذ ما يلي مع تحديد عنوان IP الخاص بـ SWP

7b827a6a38bb5afc.png

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

حدِّد المتغيّرات التالية استنادًا إلى بيئتك في مقتطف الرمز التالي:

  • PROJECT_ID
  • BUCKET_NAME
  • AGENT_NAME

في هذا الدرس العملي، ستستخدم المتغيّرَين BUCKET_NAME وAGENT_NAME لتهيئة حزمة التخزين وتكوينها لتكون متاحة على مستوى العالم.

في القسم التالي، يتم تحديد PROXY_SERVER، مثل swp.demo.com الذي يتطلّب تبادل معلومات بين الشبكات لنظام أسماء النطاقات لحلّ الاسم. في الإعدادات، يتم نشر AGENT_PEER_DOMAIN كـ demo.com. الذي يتوافق مع منطقة نظام أسماء النطاقات الخاص التي تم إنشاؤها في خطوة سابقة ضمن 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، أنشئ خلية جديدة، ونفِّذ ما يلي لإنشاء متغيّر الخادم الوكيل الذي يتوافق مع اسم المجال المؤهّل بالكامل والمنفذ الخاصين بخادم SWP.

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

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

!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

سيتم إنشاء معرّف لمحرك الاستدلال عند تنفيذ الخلية. في الخطوة التالية، ستحتاج إلى المعرّف الذي تم إنشاؤه، وهو 3235268984265768960 في هذا المثال.

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

في دفتر JupyterLab، أنشئ خلية جديدة ونفِّذ ما يلي، مع الحرص على تعديل رقم مشروعك ومعرّف استدلال Agent Engine من الناتج السابق:

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 استنادًا إلى سعر صرف الدولار الأمريكي مقابل الروبية الهندية.

f9f925983ab5cc9d.png

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

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

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

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

c9c412334a7f5ad9.png

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

e94c6c03fb51f7fe.png

13. SWP - Cloud Logging Validation

يمكنك الاطّلاع على Cloud Logging للتحقّق من عملية الخروج من الإنترنت التي تنفّذها SWP، انتقِل إلى ما يلي:

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

أدخِل الاستعلام: resource.type=" networkservices.googleapis.com/Gateway" ثم انقر على "تنفيذ الاستعلام". في ما يلي مثال يؤكّد نقطة نهاية الوجهة، api.frankfurter.app.

f53831ef8ec663db.png

fc154a5b22da2a87.png

يتحقّق مثال Cloud Logging التالي من صحة ما يلي:

Destination_range: عنوان IP لواجهة PSC الخاصة بـ Agent Engine

Source_range: Proxy Only Subnet Dest_ip: Secure Web Proxy IP Address

احرص على تغيير project_id لطلب البحث في سجلّ Cloud.

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

14. تَنظيم

في مفكرة 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

15. تهانينا

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

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

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

e6d3675ca7c6911f.jpeg

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

مزيد من المعلومات والفيديوهات

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