Agent Engine PSC Explicit Proxy

1. Giriş

Private Service Connect arayüzü, üretici Sanal Özel Bulut (VPC) ağının tüketici VPC ağındaki çeşitli hedeflerle bağlantı başlatmasına olanak tanıyan bir kaynaktır. Üretici ve tüketici ağları farklı projelerde ve kuruluşlarda olabilir.

Bir ağ eki, Private Service Connect arayüzünden gelen bağlantıyı kabul ederse Google Cloud, arayüze ağ eki tarafından belirtilen bir tüketici alt ağından IP adresi atar. Tüketici ve üretici ağları bağlıdır ve dahili IP adreslerini kullanarak iletişim kurabilir.

Ağ eki ile Private Service Connect arayüzü arasındaki bağlantı, Private Service Connect uç noktası ile hizmet eki arasındaki bağlantıya benzer ancak iki temel farkı vardır:

  • Ağ eki, üretici ağının tüketici ağına bağlantı başlatmasına (yönetilen hizmet çıkışı) olanak tanırken uç nokta, tüketici ağının üretici ağına bağlantı başlatmasına (yönetilen hizmet girişi) olanak tanır.
  • Private Service Connect arayüz bağlantısı geçişlidir. Bu, bir yapımcı ağının, tüketici ağına bağlı diğer ağlarla iletişim kurabileceği anlamına gelir.

Vertex AI PSC arayüzü erişilebilirliğiyle ilgili dikkat edilmesi gereken noktalar

  • PSC-Interface, trafiği RFC1918 adres bloğundaki VPC veya şirket içi tabanlı hedeflere yönlendirebilir.
  • RFC-1918 olmayan adres bloklarını hedefleyen PSC arayüzü, tüketicinin VPC'sinde RFC-1918 adresiyle açık bir proxy dağıtılmasını gerektirir. Vertex AI dağıtımında proxy, hedef uç noktanın tam alan adı ile birlikte tanımlanmalıdır.
  • Dağıtımınızı yalnızca bir PSC arayüzüyle yapılandırdığınızda varsayılan internet erişimi korunur. Bu giden trafik, doğrudan güvenli ve Google tarafından yönetilen kiracı ağından çıkar.

Vertex AI PSC-Interface VPC-SC ile ilgili dikkat edilmesi gereken noktalar

  • Projeniz bir VPC Hizmet Kontrolleri çevresinin parçası olduğunda, Google tarafından yönetilen kiracıların varsayılan internet erişimi, veri hırsızlığını önlemek için çevre tarafından engellenir.
  • Bu senaryoda dağıtımın genel internete erişmesine izin vermek için trafiği VPC'niz üzerinden yönlendiren güvenli bir çıkış yolu açıkça yapılandırmanız gerekir.
  • Bunu yapmanın önerilen yolu, VPC sınırınızın içinde RFC1918 adresiyle bir proxy sunucusu oluşturmak ve proxy VM'nin internete erişmesine izin vermek için bir Cloud NAT ağ geçidi oluşturmaktır.

Daha fazla bilgi için aşağıdaki kaynaklara bakın:

Temsilci dağıtma | Vertex AI'da üretken yapay zeka | Google Cloud

Vertex AI kaynakları için Private Service Connect arayüzü oluşturma | Google Cloud

Ne oluşturacaksınız?

Bu eğitimde, tüketicinin VPC'sinde bir RFC1918 adresiyle dağıtılan bir proxy sanal makinesi aracılığıyla herkese açık bir siteye (https://api.frankfurter.app/) bağlantı sağlamak için Private Service Connect (PSC) arayüzüyle dağıtılan kapsamlı bir Agent Engine oluşturacaksınız. Örnek dağıtım, VPC-SC'nin etkin olduğu bir projede veya kiracı VPC yerine müşterilerin ağı üzerinden internet çıkışı gerektiren yöneticiler için geçerlidir.

Şekil 1

f42f2db921f6d5af.png

Kiracı projesinde Agent Engine'i barındıran tüketici ağı proxy-vm'sini çözümlemek için DNS eşlemeyi kullanarak tüketici VPC'sinde tek bir psc-network-attachment oluşturursunuz. Bu işlem aşağıdaki kullanım alanlarını sağlar:

Agent Engine'i dağıtma ve açık proxy olarak hareket edecek bir proxy sanal makinesi yapılandırma. Bu sayede, https://api.frankfurter.app gibi herkese açık bir URL'ye ulaşılabilir.

Neler öğreneceksiniz?

  • Ağ eki oluşturma
  • Bir üreticinin PSC arayüzü oluşturmak için ağ eki nasıl kullanabileceği
  • DNS eşleme kullanarak üreticiden tüketiciye iletişimi nasıl kurabilirsiniz?
  • İnternet çıkışı için proxy sanal makinesi dağıtma ve kullanma

Gerekenler

Google Cloud projesi

IAM İzinleri

2. Başlamadan önce

Projeyi, eğitimi destekleyecek şekilde güncelleme

Bu eğitimde, Cloud Shell'de gcloud yapılandırmasının uygulanmasına yardımcı olmak için $değişkenleri kullanılır.

Cloud Shell'de aşağıdakileri yapın:

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

API Etkinleştirme

Cloud Shell'de aşağıdakileri yapın:

gcloud services enable "compute.googleapis.com"
gcloud services enable "aiplatform.googleapis.com"
gcloud services enable "dns.googleapis.com"
gcloud services enable "notebooks.googleapis.com"
gcloud services enable "storage.googleapis.com"
gcloud services enable "iap.googleapis.com"

API'lerin başarıyla etkinleştirildiğini doğrulayın.

gcloud services list --enabled

3. Tüketici Kurulumu

Tüketici VPC'sini oluşturma

Bu VPC, bir müşteri projesinde bulunur. Bu VPC'de aşağıdaki kaynaklar oluşturulur:

  • Tüketici Alt Ağı
  • Ağa Bağlı Alt Ağ
  • Cloud Router (Cloud NAT için gereklidir)
  • Cloud NAT

Cloud Shell'de aşağıdakileri yapın:

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

Tüketici alt ağlarını oluşturma

Cloud Shell'de Proxy VM için alt ağı oluşturun:

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

Private Service Connect ağ eki alt ağını oluşturma

Cloud Shell'de PSC ağ eki için alt ağı oluşturun:

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

Cloud Router ve NAT yapılandırması

Bu eğitimde, genel IP adresi olmayan proxy VM'ye internet erişimi sağlamak için Cloud NAT kullanılır. Cloud NAT, yalnızca özel IP adreslerine sahip sanal makinelerin internete bağlanmasını sağlayarak yazılım paketleri yükleme gibi görevleri gerçekleştirmelerine olanak tanır.

Cloud Shell'de Cloud Router'ı oluşturun.

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

Cloud Shell'de, günlük kaydı etkinleştirilmiş bir NAT ağ geçidi oluşturun. Frankfurter API'ye (https://api.frankfurter.app/) herkese açık IP üzerinden erişimi doğrulamak için günlük kaydını kullanırız.

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. IAP'yi etkinleştirme

IAP'nin sanal makine örneklerinize bağlanmasına izin vermek için aşağıdaki özellikleri içeren bir güvenlik duvarı kuralı oluşturun:

  • IAP kullanarak erişmek istediğiniz tüm sanal makine örnekleri için geçerlidir.
  • 35.235.240.0/20 IP aralığından gelen giriş trafiğine izin verir. Bu aralık, IAP'nin TCP yönlendirme için kullandığı tüm IP adreslerini içerir.

Cloud Shell'de IAP güvenlik duvarı kuralını oluşturun.

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

5. Tüketici sanal makine örnekleri oluşturma

Cloud Shell'de, Agent Engine için açık proxy görevi görecek olan tüketici sanal makine örneği proxy-vm'yi oluşturun. HTTP trafiğini proxy'lemek için tinyproxy uygulamasını kullanacağız.

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 ağ eki

Ağ ekleri, Private Service Connect arayüzünün tüketici tarafını temsil eden bölgesel kaynaklardır. Bir ağ ekiyle tek bir alt ağ ilişkilendirirsiniz ve üretici, Private Service Connect arayüzüne bu alt ağdan IP'ler atar. Alt ağ, ağ ekiyle aynı bölgede olmalıdır. Ağ eki, üretici hizmetiyle aynı bölgede olmalıdır.

Ağ eki oluşturma

Cloud Shell'de ağ ekini oluşturun.

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

Ağ eklerini listeleme

Cloud Shell'de ağ ekini listeleyin.

gcloud compute network-attachments list

Ağ eklerini açıklama

Cloud Shell'de ağ ekini açıklayın.

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

Üretici, Private Service Connect arayüzünü oluştururken kullanılacak PSC ağ eki adını (psc-network-attachment) not edin.

PSC Network Attachment URL'sini Cloud Console'da görüntülemek için şuraya gidin:

Ağ Hizmetleri → Private Service Connect → Ağ Eki → psc-network-attachment

8eec51cb197da218.png

7. Özel DNS bölgesi

demo.com için bir Cloud DNS bölgesi oluşturacak ve bu bölgeyi proxy-vm'nizin IP adreslerini gösteren bir A kaydıyla dolduracaksınız. Daha sonra, DNS eşleme Agent Engine'de dağıtılacak ve tüketicinin DNS kayıtlarına erişime izin verecek.

Cloud Shell'de, demo.com DNS adını oluşturan aşağıdaki işlemi gerçekleştirin.

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"

DNS A kayıtları için kullanılan örneklerin IP adreslerini alın ve saklayın.

Cloud Shell'de sanal makine örneklerine karşı bir açıklama işlemi gerçekleştirin.

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

Cloud Shell'de sanal makine için kayıt kümesini (proxy-vm.demo.com) oluşturun. Ortamınızın çıkışına göre IP adresini güncellediğinizden emin olun.

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 arayüzünden erişime izin verecek bir Cloud Firewall kuralı oluşturun

Aşağıdaki bölümde, PSC Ağ Eklentisi'nden kaynaklanan trafiğin tüketici VPC'sindeki proxy-vm'ye erişmesine izin veren bir güvenlik duvarı kuralı oluşturun.

Cloud Shell'de giriş güvenlik duvarı kuralını oluşturun.

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 Notebook oluşturma

Aşağıdaki bölümde, Jupyter Notebook oluşturma konusunda size yol gösterilir. Bu not defteri, internet çıkışı için açık bir proxy'yi hedefleyen Agent Engine'i dağıtmak için kullanılır.

Kullanıcı tarafından yönetilen hizmet hesabı oluşturma

Aşağıdaki bölümde, eğitimde kullanılan Vertex AI Workbench örneğiyle ilişkilendirilecek bir hizmet hesabı oluşturacaksınız.

Eğitimde, hizmet hesabına aşağıdaki roller uygulanır:

Cloud Shell'de hizmet hesabını oluşturun.

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

Cloud Shell'de hizmet hesabını Storage Admin rolüyle güncelleyin.

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

Cloud Shell'de hizmet hesabını Vertex AI Kullanıcısı rolüyle güncelleyin.

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

Cloud Shell'de hizmet hesabını Artifact Registry Yöneticisi rolüyle güncelleyin.

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

Cloud Shell'de, not defteri hizmet hesabının Compute Engine varsayılan hizmet hesabını kullanmasına izin verin.

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. Açık proxy'yi güncelleme

Aşağıdaki bölümde, açık proxy'ye SSH ile bağlanmanız ve tinyproxy.conf yapılandırma dosyasını güncelleyip sıfırlama işlemini gerçekleştirmeniz gerekir.

Cloud Shell'den

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

tinyproxy yapılandırma dosyasını açın ve tercih ettiğiniz düzenleyiciyi kullanarak güncelleyin. Aşağıda VIM'in kullanıldığı bir örnek verilmiştir.

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 örneği oluşturma

Aşağıdaki bölümde, daha önce oluşturulan hizmet hesabını (notebook-sa) içeren bir Vertex AI Workbench örneği oluşturun.

Cloud Shell'de private-client örneğini oluşturun.

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 Service Agent Update

Vertex AI, PSC arayüzünü oluşturmak için kullanılan PSC Ağ Eki alt ağından IP adresi alma gibi işlemleri sizin adınıza gerçekleştirir. Vertex AI, bunu yapmak için Ağ Yöneticisi izni gerektiren bir hizmet aracısı (aşağıda listelenmiştir) kullanır:

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

Cloud Shell'de proje numaranızı alın.

gcloud projects describe $projectid | grep projectNumber

Cloud Shell'de proje numaranızı ayarlayın.

projectnumber=YOUR-PROJECT-Number

Cloud Shell'de AI Platform için bir hizmet hesabı oluşturun. Projenizde mevcut bir hizmet hesabınız varsa bu adımı atlayın.

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

Cloud Shell'de, hizmet aracısı hesabını compute.networkAdmin rolüyle güncelleyin.

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

Cloud Shell'de hizmet aracısı hesabını dns.peer rolüyle güncelleyin.

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

Varsayılan Hizmet Hesabı Güncellemesi

Varsayılan hizmet hesabınıza Vertex AI'a erişim izni verin. Erişim değişikliğinin geçerlilik kazanması biraz zaman alabilir.

Cloud Shell'de varsayılan hizmet hesabını aiplatform.user rolüyle güncelleyin.

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

12. Proxy VM Tcpdump

Aracı motorundan IP bağlantısını doğrulamak için TCPDUMP'ı kullanabiliriz. Bu sayede, Agent Engine'den herkese açık URL'ye get isteği çağrıldığında PSC Network Attachment alt ağından (192.168.10.0/28) kaynaklanan iletişimi gözlemleyebiliriz.

Cloud Shell'den proxy sanal makinesine SSH üzerinden bağlanın.

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

Proxy-vm işletim sisteminden tcpdump'ı çalıştırın.

sudo tcpdump -i any net 192.168.10.0/28 -nn

13. Agent Engine'i dağıtma

Not: Bu bölümdeki görevleri tamamlamak için GCP Console ve JupyterLab not defterini kullanacağız.

Aşağıdaki bölümde, şu görevleri gerçekleştiren bir not defteri oluşturacaksınız:

  • Döviz kuru verilerini almak için Frankfurter API'yi (https://api.frankfurter.app/) kullanır.
  • FQDN proxy-vm.demo.com kullanılarak tüketicilerin VPC'sindeki proxy-vm'yi hedefleyen açık bir proxy'ye (proxy_server) referans verir.
  • dnsPeeringConfigs "domain": "demo.com." öğesini tanımlayın.

Eğitim işini Vertex AI Workbench örneğinde çalıştırma

  • Google Cloud Console'da Vertex AI → Workbench'e gidin.
  • Vertex AI Workbench örneğinizin (workbench-tutorial) adının yanındaki Open JupyterLab'i (JupyterLab'i aç) tıklayın. Vertex AI Workbench örneğiniz JupyterLab'de açılır.
  • Dosya > Yeni > Not defteri'ni seçin.
  • Çekirdek > Python 3'ü seçin.

Gerekli Python kitaplıklarını yükleyin: pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys ve langchain-google-vertexai dahil olmak üzere Agent Engine için gerekli kitaplıkları yükleyin.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

!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 çekirdeğini yeniden başlatın: Yeni yüklenen kitaplıkların doğru şekilde yüklendiğinden emin olun.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

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

import IPython

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

Proje ve paket değişkenlerini ayarlayın: Google Cloud proje kimliğinizi, proje numaranızı, hizmet adınızı, GCS dizininizi, uç noktanızı, paket adınızı ve konumunuzu tanımlayın.

Hücreyi çalıştırmadan önce aşağıdaki alanları güncelleyin

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

Not: Sonraki adımda Cloud Storage paketi oluşturmak için BUCKET değişkenini kullanacağız.

JupyterLab not defterinizde yeni bir hücre oluşturun, aşağıdakileri güncelleyin ve çalıştırın.

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 paketi oluşturun: Aracı kodunu depolamak için bir Cloud Storage paketi oluşturun.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

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

Ağ eki adını tanımlayın: Private Service Connect ağ ekinizin adını belirtin.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

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

Python istemci kitaplıklarını başlatın: Google Cloud hizmetleri için gerekli istemci kitaplıklarını ayarlayın.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

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)

Aracı ve araçları yapılandırma: Açık proxy üzerinden Frankfurter API'yi kullanarak döviz kurlarını getirmek için StreamingAgent sınıfını ve get_exchange_rate işlevini tanımlayın.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdaki yapılandırmayı çalıştırın. Aşağıdaki önemli noktaları unutmayın:

  • def get_exchange_rate işlevi, döviz kuru verilerini almak için Frankfurter API'yi (https://api.frankfurter.app/) kullanır.
  • proxy_server = "http://proxy-vm.demo.com:8888" FQDN, tüketici VPC'sinde dağıtılan proxy VM ile ilişkilidir. FQDN'yi sonraki bir adımda çözmek için DNS eşlemesini kullanıyoruz.
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()

Aracı dosyalarını Cloud Storage'a yükleme: Serileştirilmiş aracı ve gereksinimlerini, belirlenen GCS paketinize yükleyin.

JupyterLab not defterinizde yeni bir hücre oluşturup aşağıdakileri çalıştırın:

# 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'i dağıtma: Agent Engine'i dağıtın, tüketici VPC'sindeki proxy VM'nin FQDN'sini çözmek için PSC arayüzü ve DNS eşlemesiyle yapılandırın.

JupyterLab not defterinizde aşağıdaki hücreyi oluşturup çalıştırın. Aşağıdaki önemli noktaları unutmayın:

  • Tüketici VPC'leri ile DNS eşlemesi, demo.com alan adı için dnsPeeringConfigs (dnsPeeringConfigs) kullanılarak yapılandırılır.
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)

Dağıtım durumunu izleme: Agent Engine dağıtım işleminin durumunu kontrol edin.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

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

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

Not: Bu işlemin tamamlanması yaklaşık 5 dakika sürebilir. İlerleme durumunu kontrol etmek için hücreyi yeniden çalıştırın. Lütfen aşağıdaki ekran görüntüsüne benzer bir çıkış görmeden bir sonraki bölüme geçmeyin.

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

Başarılı bir çalıştırma örneği:

3f6dcd1074af7651.png

Dağıtılan temsilciye sorgu gönderme: İşlevselliğini test etmek için dağıtılan Agent Engine'e sorgu gönderin.

JupyterLab not defterinizde yeni bir hücre oluşturun ve aşağıdakileri çalıştırın.

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)

Sorgu sonuçlarını yayınlama: Agent Engine sorgusunun çıkışını yayınlayın.

JupyterLab not defterinizde yeni bir hücre oluşturun ve tüketicilerin VPC'sindeki açık proxy'yi kullanarak herkese açık URL'ye API çağrısını tetikleyecek aşağıdaki kodu çalıştırın.

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

Başarılı bir çalıştırma örneği:

1bd81d12426a348f.png

14. Tcpdump Doğrulaması

İstek gönderildikten sonra Agent Engine tarafından kullanılan PSC ağ eki IP adresi ile Prox-VM arasındaki iletişimi ayrıntılı olarak açıklayan tcpdump çıkışını görüntüleyin.

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 Arayüzü Doğrulaması

Ayrıca, aşağıdakine giderek Agent Engine tarafından kullanılan ağ eki IP'lerini de görüntüleyebilirsiniz:

Ağ Hizmetleri → Private Service Connect → Ağ Eki → psc-network-attachment

Kiracı projesini seçin (proje adı -tp ile biter).

8a4b5a6e5dfd63d7.png

Vurgulanan alan, PSC Ağ Eki'nden Agent Engine tarafından kullanılan IP adresini gösterir.

c618359f6eafc0c6.png

16. Cloud Logging Validation

Proxy-vm TCPDump oturumundan çıkın ve ilişkili herkese açık IP adresini almak için Frankfurter api.frankfurter.app'e PING işlemi uygulayın.

ping -c4 api.frankfurter.app 

Örnek, 104.26.1.198'i api.frankfurter.app için herkese açık IP olarak tanımlar.

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

104.26.1.198 trafiğinin gözlemlenip gözlemlenmediğini görmek için NAT Günlüğü'ne bakalım.

Aşağıdakilere gidin:

İzleme → Günlük Gezgini

Aşağıdaki filtreyi kullanın:

resource.type="nat_gateway"

31024dc29c39084.png

Zaman aralığını seçin ve ardından Sorguyu Çalıştır'ı tıklayın.

5976857e92d149d3.png

api.frankfurter.app'in (hedef) herkese açık IP'sini (104.26.1.198) ve internet çıkışı için açık proxy kullanımını doğrulayan proxy-vm'nin kaynak IP adresini ve adını tanımlayan günlük girişini genişletin.

14e293a7fea68db4.png

17. Temizleme

JupyterLab not defterinizde yeni bir hücre oluşturun ve Agent Engine dağıtımının silinmesini tetikleyecek aşağıdaki kodu çalıştırın.

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'den eğitim bileşenlerini silin.

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. Tebrikler

Tebrikler! İnternet çıkışı açık bir proxy üzerinden gerçekleştirilen Private Service Connect arayüzü ile dağıtılan Agent Engine'i başarıyla yapılandırdınız ve doğruladınız.

Tüketici altyapısını oluşturdunuz ve üreticinin tüketici ile üretici arasındaki iletişimi köprülemek için çoklu NIC VM oluşturmasına olanak tanıyan bir ağ eki eklediniz. İnternet bağlantısına izin veren açık proxy ve DNS eşlemesi oluşturmayı öğrendiniz.

Cosmopup, eğitimlerin harika olduğunu düşünüyor.

c911c127bffdee57.jpeg

Yapabilecekleriniz

Daha fazla bilgi ve videolar

Referans belgeleri