1. はじめに
Private Service Connect インターフェースは、プロデューサーの Virtual Private Cloud(VPC)ネットワークがコンシューマーの VPC ネットワーク内のさまざまな宛先への接続を開始できるようにするためのリソースです。プロデューサー ネットワークとコンシューマー ネットワークは、異なるプロジェクトや組織に属していてもかまわない。
ネットワーク アタッチメントが Private Service Connect インターフェースからの接続を受け入れると、Google Cloud はネットワーク アタッチメントで指定されたコンシューマー サブネットからインターフェースに IP アドレスを割り振ります。コンシューマ ネットワークとプロデューサー ネットワークが接続され、内部 IP アドレスを使用して通信が可能になります。
ネットワーク アタッチメントと Private Service Connect インターフェース間の接続は、Private Service Connect のエンドポイントとサービス アタッチメント間の接続に似ていますが、重要な違いが 2 つあります。
- ネットワーク アタッチメントは、プロデューサー ネットワークからコンシューマー ネットワークへの接続(マネージド サービスの下り、外向き)を開始できるようにします。エンドポイントは、コンシューマー ネットワークからプロデューサー ネットワークへの接続(マネージド サービスの上り、内向き)を開始できるようにします。
- Private Service Connect インターフェースの接続は推移的です。これは、プロデューサー ネットワークは、コンシューマー ネットワークに接続されている他のネットワークと通信できることを意味します。
Vertex AI PSC インターフェースの到達可能性に関する考慮事項
- PSC インターフェースは、RFC1918 アドレス ブロック内の VPC またはオンプレミス ベースの宛先にトラフィックをルーティングできます。
- RFC 1918 以外のアドレス ブロックをターゲットとする PSC インターフェースでは、RFC 1918 アドレスを使用してコンシューマーの VPC に明示的なプロキシをデプロイする必要があります。Vertex AI デプロイ内で、プロキシはターゲット エンドポイントの FQDN とともに定義する必要があります。図 1 は、次の非 rfc-1918 CIDR へのルーティングを容易にするために、お客様の VPC で構成された明示的プロキシを表しています。
[1] 240.0.0.0/4
[2] 203.0.113.0/2
[3]10.10.20.0/28 プロキシは不要です。rfc1918 範囲に該当します。
- PSC インターフェースのみを使用してデプロイを構成すると、デフォルトのインターネット アクセスが保持されます。このアウトバウンド トラフィックは、Google が管理する安全なテナント ネットワークから直接送信されます。
Vertex AI PSC-Interface VPC-SC に関する考慮事項
- プロジェクトが VPC Service Controls の境界に含まれている場合、データ漏洩を防ぐために、Google マネージド テナントのデフォルトのインターネット アクセスは境界によってブロックされます。
- このシナリオでデプロイがパブリック インターネットにアクセスできるようにするには、VPC を介してトラフィックをルーティングする安全な下り(外向き)パスを明示的に構成する必要があります。この目的を達成するおすすめの方法は、RFC1918 アドレスを使用して VPC ペリメータ内にプロキシ サーバーを設定し、プロキシ VM がインターネットにアクセスできるように Cloud NAT ゲートウェイを作成することです。
詳しくは、次のリソースをご覧ください。
Vertex AI リソースの Private Service Connect インターフェースを設定する | Google Cloud
作成するアプリの概要
このチュートリアルでは、図 1 に示すように、プロデューサーからコンシューマーのコンピューティングへの接続を可能にする Private Service Connect(PSC)インターフェースを使用して、包括的な Vertex AI Pipelines デプロイを構築します。このデプロイは、rfc-1928 以外のエンドポイントをターゲットとしています。
図 2
コンシューマー VPC に単一の psc-network-attachment を作成し、DNS ピアリングを利用して Vertex AI Training をホストするテナント プロジェクト内のコンシューマー VM を解決します。これにより、次のユースケースが実現します。
- Vertex AI Pipelines をデプロイし、明示的なプロキシとして機能するようにプロキシ VM を構成して、クラス E サブネット内の VM に対して wget を実行できるようにします。
学習内容
- ネットワーク アタッチメントを作成する方法
- プロデューサーがネットワーク アタッチメントを使用して PSC インターフェースを作成する方法
- DNS ピアリングを使用してプロデューサーからコンシューマーへの通信を確立する方法
- Vertex AI Pipelines から非 rfc1918 IP アドレス空間への通信を確立する方法
必要なもの
Google Cloud プロジェクト
IAM 権限
- Compute ネットワーク管理者 (roles/compute.networkAdmin)
- Compute インスタンス管理者 (roles/compute.instanceAdmin)
- Compute セキュリティ管理者(roles/compute.securityAdmin)
- DNS 管理者(roles/dns.admin)
- IAP で保護されたトンネル ユーザー(roles/iap.tunnelResourceAccessor)
- Logging 管理者(roles/logging.admin)
- Notebooks 管理者(roles/notebooks.admin)
- Project IAM 管理者(roles/resourcemanager.projectIamAdmin)
- サービス アカウント管理者(roles/iam.serviceAccountAdmin)
- Service Usage 管理者(roles/serviceusage.serviceUsageAdmin)
2. 始める前に
チュートリアルをサポートするようにプロジェクトを更新する
このチュートリアルでは、$variables を使用して、Cloud Shell での gcloud 構成の実装を支援します。
Cloud Shell で、次の操作を行います。
gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid
API の有効化
Cloud Shell で、次の操作を行います。
gcloud services enable "compute.googleapis.com"
gcloud services enable "aiplatform.googleapis.com"
gcloud services enable "dns.googleapis.com"
gcloud services enable "notebooks.googleapis.com"
gcloud services enable "storage.googleapis.com"
gcloud services enable "cloudresourcemanager.googleapis.com"
gcloud services enable "artifactregistry.googleapis.com"
gcloud services enable "cloudbuild.googleapis.com"
3. コンシューマーの設定
コンシューマー VPC を作成する
Cloud Shell で、次の操作を行います。
gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom
コンシューマー サブネットを作成する
Cloud Shell で、次の操作を行います。
gcloud compute networks subnets create class-e-subnet --project=$projectid --range=240.0.0.0/4 --network=consumer-vpc --region=us-central1
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 で、次の操作を行います。
gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1
Cloud Router と NAT の構成
このチュートリアルでは、パブリック IP アドレスを持たないプロキシ VM にインターネット アクセスを提供するために Cloud NAT を使用します。Cloud NAT を使用すると、プライベート IP アドレスのみを持つ VM がインターネットに接続して、ソフトウェア パッケージのインストールなどのタスクを実行できます。
Cloud Shell 内で、Cloud Router を作成します。
gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1
Cloud Shell 内で、NAT ゲートウェイを作成します。
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 を有効にする
IAP に VM インスタンスへの接続を許可するには、次のファイアウォール ルールを作成します。
- IAP を使用してアクセス可能にするすべての VM インスタンスに適用されます。
- IP 範囲 35.235.240.0/20 からの上り(内向き)トラフィックを許可します。この範囲には、IAP が TCP 転送に使用するすべての IP アドレスが含まれています。
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. コンシューマー VM インスタンスを作成する
Cloud Shell 内で、コンシューマー VM インスタンス class-e-vm を作成します。
gcloud compute instances create class-e-vm \
--project=$projectid \
--machine-type=e2-micro \
--image-family debian-11 \
--no-address \
--shielded-secure-boot \
--image-project debian-cloud \
--zone us-central1-a \
--subnet=class-e-subnet \
--metadata startup-script="#! /bin/bash
sudo apt-get update
sudo apt-get install tcpdump
sudo apt-get install apache2 -y
sudo service apache2 restart
echo 'Class-e server !!' | tee /var/www/html/index.html
EOF"
Cloud Shell 内で、Vertex AI Pipelines の明示的なプロキシとして機能するコンシューマー VM インスタンス proxy-vm を作成します。HTTPS もサポートされていますが、HTTP トラフィックのプロキシ アプリケーションとして tinyproxy を使用します。
gcloud compute instances create proxy-vm \
--project=$projectid \
--machine-type=e2-micro \
--image-family debian-11 \
--no-address \
--can-ip-forward \
--shielded-secure-boot \
--image-project debian-cloud \
--zone us-central1-a \
--subnet=rfc1918-subnet1 \
--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 インターフェースのコンシューマー側を表すリージョン リソースです。単一のサブネットをネットワーク アタッチメントに関連付けると、プロデューサーはそのサブネットから Private Service Connect インターフェースに IP を割り当てます。サブネットは、ネットワーク アタッチメントと同じリージョンに存在する必要があります。ネットワーク アタッチメントは、プロデューサー サービスと同じリージョンに存在する必要があります。
ネットワーク アタッチメントを作成する
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
プロデューサーが Private Service Connect インターフェースを作成するときに使用する psc-network-attachment という名前の psc-network-attachment をメモします。
Cloud Console で PSC ネットワーク アタッチメントの URL を表示するには、次の場所に移動します。
[ネットワーク サービス] → [Private Service Connect] → [ネットワーク アタッチメント] → [psc-network-attachment]
7. 限定公開 DNS ゾーン
demo.com の Cloud DNS ゾーンを作成し、VM の IP アドレスを指す A レコードを入力します。その後、DNS ピアリングが Vertex AI Pipelines ジョブにデプロイされ、コンシューマーの DNS レコードにアクセスできるようになります。
Cloud Shell で、次の操作を行います。
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"
Cloud Shell 内で、VM インスタンスに対して説明を実行して、それぞれの IP アドレスを取得します。
gcloud compute instances describe class-e-vm --zone=us-central1-a | grep networkIP:
gcloud compute instances describe proxy-vm --zone=us-central1-a | grep networkIP:
Cloud Shell 内で、VM(class-e-vm)のレコード セットを作成します。環境の出力に基づいて IP アドレスを更新してください。
gcloud dns --project=$projectid record-sets create class-e-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="240.0.0.2"
Cloud Shell で、VM と proxy-vm のレコード セットを作成します。環境の出力に基づいて 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 インターフェースからのアクセスを許可する Cloud Firewall ルールを作成する
次のセクションでは、PSC ネットワーク アタッチメントから送信されたトラフィックがコンシューマー VPC の RFC1918 コンピューティング リソースにアクセスできるようにするファイアウォール ルールを作成します。
Cloud Shell で、PSC ネットワーク アタッチメント サブネットから proxy-vm へのアクセスを許可する上り(内向き)ファイアウォール ルールを作成します。
gcloud compute firewall-rules create allow-access-to-proxy \
--network=consumer-vpc \
--action=ALLOW \
--rules=ALL \
--direction=INGRESS \
--priority=1000 \
--source-ranges="192.168.10.0/28" \
--destination-ranges="10.10.0.0/19" \
--enable-logging
Cloud Shell で、プロキシ VM サブネットから class-e サブネットへのアクセスを許可する上り(内向き)ファイアウォール ルールを作成します。
gcloud compute firewall-rules create allow-access-to-class-e \
--network=consumer-vpc \
--action=ALLOW \
--rules=ALL \
--direction=INGRESS \
--priority=1000 \
--source-ranges="10.10.10.0/28" \
--destination-ranges="240.0.0.0/4" \
--enable-logging
8. 明示的プロキシを更新する
次のセクションでは、明示的プロキシに 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
9. Jupyter ノートブックを作成する
次のセクションでは、Jupyter Notebook の作成について説明します。このノートブックは、Vertex AI Pipelines からテスト インスタンスに wget を送信する Vertex AI Pipelines ジョブをデプロイするために使用されます。インスタンスを含む Vertex AI Pipelines とコンシューマー ネットワーク間のデータパスは、Private Service Connect ネットワーク インターフェースを使用します。
ユーザー管理のサービス アカウントを作成する
次のセクションでは、チュートリアルで使用する 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 内で、Cloud Build 編集者のロールを持つサービス アカウントを更新します。
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/cloudbuild.builds.editor"
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"
10. Vertex AI Workbench インスタンスを作成する
次のセクションでは、前に作成したサービス アカウント notebook-sa を組み込んだ Vertex AI Workbench インスタンスを作成します。
Cloud Shell 内で private-client インスタンスを作成します。
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 は、PSC インターフェースの作成に使用される PSC ネットワーク アタッチメント サブネットから IP アドレスを取得するなどのオペレーションをユーザーに代わって実行します。そのため、Vertex AI は ネットワーク管理者権限を必要とするサービス エージェント(下記)を使用します。
service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com
Cloud Shell で、プロジェクト番号を取得します。
gcloud projects describe $projectid | grep projectNumber
Cloud Shell で、プロジェクト番号を取得します。
gcloud projects describe $projectid | grep projectNumber
projectNumber: '234086459238'
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"
デフォルトのサービス アカウントの更新
Compute Engine API を有効にして、Vertex AI へのアクセス権をデフォルトのサービス アカウントに付与します。アクセス権の変更が反映されるまでに時間がかかることがあります。
Cloud Shell 内で、デフォルトのサービス アカウントを aiplatform.user ロールで更新します。
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/aiplatform.user"
Cloud Shell 内で、ロール storage.admin を使用してデフォルトのサービス アカウントを更新します。
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/storage.admin"
Cloud Shell 内で、ロール storage.admin を使用してデフォルトのサービス アカウントを更新します。
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.admin"
12. Tcpdump を有効にする
Vertex AI Pipelines からの IP 接続を検証するには、TCPDUMP を使用します。これにより、Vertex AI Pipelines から vm(class-e-vm.demo.com(240.0.0.0/4))に get リクエストを呼び出すときに、PSC ネットワーク アタッチメント サブネット(192.168.10.0/28)から発信される通信をモニタリングできます。
Cloud Shell からプロキシ VM に ssh で接続します。
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
proxy-vm OS から、class-e-vm と PSC ネットワーク アタッチメント サブネットで tcpdump フィルタリングを実行します。
sudo tcpdump -i any net 240.0.0.0/4 or 192.168.10.0/28 -nn
新しい Cloud Shell タブを開き、プロジェクト変数を更新して、class-e-vm に SSH で接続します。
gcloud compute ssh --zone us-central1-a "class-e-vm" --tunnel-through-iap --project $projectid
class-e-vm OS から、proxy-vm サブネットで tcpdump フィルタリングを実行します。
sudo tcpdump -i any net 10.10.10.0/28 -nn
13. Vertex AI Pipelines ジョブをデプロイする
次のセクションでは、Vertex AI Pipelines から明示的なプロキシへの wget を正常に実行するノートブックを作成します。これにより、class-e-vm などの RFC 1918 以外の VM に到達できます。Vertex AI Pipelines が rfc1918-vm にアクセスする場合、ターゲットは RFC 1918 IP アドレスであるため、明示的なプロキシは必要ありません。
Vertex AI Workbench インスタンスでトレーニング ジョブを実行します。
- Google Cloud コンソールで、Vertex AI Workbench ページの [インスタンス] タブに移動します。
- Vertex AI Workbench インスタンス名(workbench-tutorial)の横にある [JupyterLab を開く] をクリックします。JupyterLab で Vertex AI Workbench インスタンスが開きます。
- [ファイル] > [新規] > [ノートブック] の順に選択します。
- [Kernel] > [Python 3] を選択します。
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
# Install gcloud
!pip install google-cloud
# Install the pipeline required packages
!pip install --upgrade google-cloud-aiplatform \
google-cloud-storage \
kfp \
google-cloud-pipeline-components
# Import libraries
from time import gmtime, strftime
import json
import requests
JupyterLab ノートブックで、新しいセルを作成し、次の内容を更新して実行します。PROJECT_ID は、環境の詳細に置き換えてください。
import json
import requests
import pprint
PROJECT_ID = 'YOUR-PROJECT-ID' #Enter your project ID
PROJECT_NUMBER=!gcloud projects list --filter="project_id:$PROJECT_ID" --format="value(PROJECT_NUMBER)"
PROJECT_NUMBER=str(PROJECT_NUMBER).strip('[').strip(']').strip("'")
print(PROJECT_NUMBER)
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
# us-central1 is used for the codelab
REGION = "us-central1" #@param {type:"string"}
SERVICE_NAME = "aiplatform" #@param {type:"string"}
SERVICE ="{}.googleapis.com".format(SERVICE_NAME)
ENDPOINT="{}-{}.googleapis.com".format(REGION, SERVICE_NAME)
API_VERSION = "v1" # @param {type: "string"}
LOCATION = REGION
JupyterLab ノートブックで、新しいセルを作成して次の構成を実行します。次の点に注意してください。
- proxy_server = "http://proxy-vm.demo.com:8888" FQDN は、コンシューマー VPC にデプロイされたプロキシ VM に関連付けられています。後の手順で DNS ピアリングを使用して FQDN を解決します。
%%writefile main.py
import logging
import socket
import sys
import os
def make_api_request(url: str, proxy_vm_ip: str, proxy_vm_port: str):
"""
Makes a GET request to a non-rfc1918 API and saves the response.
Args:
url: The URL of the API to send the request to.
"""
import requests
try:
# response = requests.get(url)
proxy_server = f"http://proxy-vm.demo.com:8888" # replace with you VM's IP and proxy port.
proxies = {
"http": proxy_server,
"https": proxy_server,
}
response = requests.get(url, proxies=proxies)
logging.info(response.text)
response.raise_for_status() # Raise an exception for bad status codes
logging.info(f"Successfully fetched data from {url}")
except requests.exceptions.RequestException as e:
logging.error(f"An error occurred: {e}")
raise e
if __name__ == '__main__':
# Configure logging to print clearly to the console
logging.basicConfig(
level=logging.INFO,
format='%(levelname)s: %(message)s',
stream=sys.stdout
)
url_to_test = os.environ['NONRFC_URL']
proxy_vm_ip = os.environ['PROXY_VM_IP']
proxy_vm_port = os.environ['PROXY_VM_PORT']
logging.info(f"url_to_test: {url_to_test}")
logging.info(f"proxy_vm_ip: {proxy_vm_ip}")
logging.info(f"proxy_vm_port: {proxy_vm_port}")
make_api_request(url_to_test, proxy_vm_ip, proxy_vm_port)
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
%%writefile Dockerfile
FROM python:3.9-slim
RUN apt-get update && \
apt-get install -y iputils-ping && \
apt-get install -y wget
RUN pip install cloudml-hypertune requests kfp
COPY main.py /main.py
ENTRYPOINT ["python3", "/main.py"]
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
!gcloud artifacts repositories create pipelines-test-repo-psc --repository-format=docker --location=us-central1
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
IMAGE_PROJECT = PROJECT_ID
IMAGE_REPO = 'pipelines-test-repo-psc'
IMAGE_NAME = 'nonrfc-ip-call'
TAG = 'v1'
IMAGE_URI= f'us-central1-docker.pkg.dev/{IMAGE_PROJECT}/{IMAGE_REPO}/{IMAGE_NAME}:{TAG}'
IMAGE_URI
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
!gcloud auth configure-docker us-docker.pkg.dev --quiet
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。エラー(gcloud.builds.submit)が表示された場合は無視します。
!gcloud builds submit --tag {IMAGE_URI} --region=us-central1
JupyterLab ノートブックで次のセルを作成して実行します。次の点に注意してください。
- コンシューマー VPC への DNS ピアリングは、ドメイン名 demo.com の dnsPeeringConfigs(dnsPeeringConfigs)を使用して構成されます。
- 変数 PROXY_VM_IP として定義された明示的プロキシは proxy-vm.demo.com です。解決は、コンシューマーの VPC 内の DNS ピアリングによって処理されます。
- ポート 8888 は、tinyproxy で構成されたリッスンポート(デフォルト)です。
- class-e-vm-demo.com への Wget は DNS ピアリングで解決される
- このコードは Vertex の「psc-network-attachment」を指定し、ネットワーク アタッチメント サブネットを使用して 2 つの PSC インターフェース インスタンスをデプロイできるようにします。
import json
from datetime import datetime
JOB_ID_PREFIX='test_psci-nonRFC' #@param {type:"string"}
JOB_ID = '{}_{}'.format(JOB_ID_PREFIX, datetime.now().strftime("%Y%m%d%H%M%S"))
# PSC-I configs
PRODUCER_PROJECT_ID = PROJECT_ID
DNS_DOMAIN = 'class-e-vm.demo.com' #@param {type:"string"}
NON_RFC_URL = f"http://{DNS_DOMAIN}"
PROXY_VM_IP = "proxy-vm.demo.com" #@param {type:"string"}
PROXY_VM_PORT = "8888" #@param {type:"string"}
CUSTOM_JOB = {
"display_name": JOB_ID,
"job_spec": {
"worker_pool_specs": [
{
"machine_spec": {
"machine_type": "n1-standard-4",
},
"replica_count": 1,
"container_spec": {
"image_uri": IMAGE_URI,
"env": [{
"name": "NONRFC_URL",
"value": NON_RFC_URL
},
{
"name": "PROXY_VM_IP",
"value": PROXY_VM_IP
},
{
"name": "PROXY_VM_PORT",
"value": PROXY_VM_PORT
}]
},
},
],
"enable_web_access": True,
"psc_interface_config": {
"network_attachment": "psc-network-attachment",
"dns_peering_configs": [
{
"domain": "demo.com.",
"target_project": PROJECT_ID,
"target_network": "consumer-vpc"
},
]
},
}
}
print(json.dumps(CUSTOM_JOB, indent=2))
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
import requests
bearer_token = !gcloud auth application-default print-access-token
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {}'.format(bearer_token[0]),
}
request_uri = f"https://{REGION}-aiplatform.googleapis.com/{API_VERSION}/projects/{PROJECT_NUMBER}/locations/{REGION}/customJobs/"
print("request_uri: ", request_uri)
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
response_autopush = requests.post(request_uri, json=CUSTOM_JOB, headers=headers)
response = response_autopush
print("response:", response)
if response.reason == 'OK':
job_name = response.json()['name']
job_id = job_name.split('/')[-1]
print("Created Job: ", response.json()['name'])
else:
print(response.text)
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
# Print KFP SDK version (should be >= 1.6)
! python3 -c "import kfp; print('KFP SDK version: {}'.format(kfp.__version__))"
# Print AI Platform version
! python3 -c "from google.cloud import aiplatform; print('AI Platform version: {}'.format(aiplatform.__version__))"
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
BUCKET_URI = "your-unique-bucket" # Provide a globally unique bucket name
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
!gcloud storage buckets create gs://{BUCKET_URI}
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
# pipeline parameters
CACHE_PIPELINE = False # @param {type: "string"}
_DEFAULT_IMAGE = IMAGE_URI
BUCKET_URI = "gs://{BUCKET_URI}" # @param {type: "string"}
PIPELINE_ROOT = f"{BUCKET_URI}/pipeline_root/intro"
PIPELINE_DISPLAY_NAME = "pipeline_nonRFCIP" # @param {type: "string"}
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
from re import S
import kfp
from kfp import dsl
from kfp.dsl import container_component, ContainerSpec
from kfp import compiler
from google.cloud import aiplatform
# ==== Component with env variable ====
@container_component
def dns_peering_test_op(dns_domain: str, proxy_vm_ip:str, proxy_vm_port:str):
return ContainerSpec(
image=_DEFAULT_IMAGE,
command=["bash", "-c"],
args=[
"""
apt-get update && apt-get install inetutils-traceroute inetutils-ping netcat-openbsd curl -y
echo "Local IP(s): $(hostname -I)"
echo "Attempting to trace route to %s"
traceroute -w 1 -m 7 "%s"
echo "Sending curl requests to http://%s via proxy %s:%s and recording trace..."
if curl -L -v --trace-ascii /dev/stdout -x http://%s:%s "http://%s"; then
echo "Curl request succeeded!"
else
echo "Curl request failed!"
exit 1
fi
""" % (dns_domain, dns_domain, dns_domain, proxy_vm_ip, proxy_vm_port, proxy_vm_ip, proxy_vm_port, dns_domain)
]
)
# ==== Pipeline ====
@dsl.pipeline(
name="dns-peering-test-pipeline",
description="Test DNS Peering using env variable",
pipeline_root=PIPELINE_ROOT,
)
def dns_peering_test_pipeline(dns_domain: str, proxy_vm_ip:str, proxy_vm_port:str):
dns_test_task = dns_peering_test_op(dns_domain=dns_domain, proxy_vm_ip=proxy_vm_ip, proxy_vm_port=proxy_vm_port)
dns_test_task.set_caching_options(enable_caching=CACHE_PIPELINE)
# ==== Compile pipeline ====
if __name__ == "__main__":
aiplatform.init(project=PROJECT_ID, location=LOCATION)
compiler.Compiler().compile(
pipeline_func=dns_peering_test_pipeline,
package_path="dns_peering_test_pipeline.yaml",
)
print("✅ Pipeline compiled to dns_peering_test_pipeline.yaml")
JupyterLab ノートブックで、新しいセルを作成して次のコマンドを実行します。
# Define the PipelineJob body; see API Reference https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.pipelineJobs/create
import requests, json
import datetime
bearer_token = !gcloud auth application-default print-access-token
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {}'.format(bearer_token[0]),
}
request_uri = f"https://{REGION}-aiplatform.googleapis.com/{API_VERSION}/projects/{PROJECT_NUMBER}/locations/{REGION}/pipelineJobs/"
print("request_uri: ", request_uri)
14. PSC インターフェースの検証
次の場所に移動して、Vertex AI Pipelines で使用されるネットワーク アタッチメントの IP を確認することもできます。
[ネットワーク サービス] → [Private Service Connect] → [ネットワーク アタッチメント] → [psc-network-attachment]
テナント プロジェクト(-tp で終わるプロジェクト名)を選択します。
ハイライト表示されたフィールドは、PSC ネットワーク アタッチメントから Vertex AI Pipelines で使用される IP アドレスを示します。
15. Cloud Logging の検証
Vertex AI Pipelines ジョブの初回実行には約 14 分かかりますが、以降の実行ははるかに短時間で完了します。成功した結果を検証するには、次の操作を行います。
[Vertex AI] → [トレーニング] → [カスタムジョブ] に移動します。
実行されたカスタムジョブを選択する
[ログを表示] を選択する
Cloud Logging が使用可能になったら、ハイライト表示された選択肢を生成するクエリを実行します。これにより、Vertex AI Pipelines から class-e-vm への wget が成功したことが確認されます。
16. TCPDump の検証
コンピューティング インスタンスへの接続をさらに検証する TCPDUMP 出力を確認してみましょう。
proxy-vm から HTTP GET と 200 OK を確認します。
03:05:34.778574 ens4 Out IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 1:63, ack 1, win 511, options [nop,nop,TS val 1435446009 ecr 2475360885], length 62: HTTP: GET / HTTP/1.0 03:05:34.778946 ens4 In IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 63, win 506, options [nop,nop,TS val 2475360889 ecr 1435446009], length 0 03:05:34.778974 ens4 Out IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 63:185, ack 1, win 511, options [nop,nop,TS val 1435446010 ecr 2475360889], length 122: HTTP 03:05:34.781999 ens4 In IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 185, win 506, options [nop,nop,TS val 2475360892 ecr 1435446010], length 0 03:05:34.906678 ens4 In IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [P.], seq 1:265, ack 185, win 506, options [nop,nop,TS val 2475361016 ecr 1435446010], length 264: HTTP: HTTP/1.1 200 OK
class-e-vm から HTTP GET と 200 OK を確認する
03:05:34.778768 ens4 In IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 1:63, ack 1, win 511, options [nop,nop,TS val 1435446009 ecr 2475360885], length 62: HTTP: GET / HTTP/1.0 03:05:34.778819 ens4 Out IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 63, win 506, options [nop,nop,TS val 2475360889 ecr 1435446009], length 0 03:05:34.781815 ens4 In IP 10.10.10.2.40326 > 240.0.0.2.80: Flags [P.], seq 63:185, ack 1, win 511, options [nop,nop,TS val 1435446010 ecr 2475360889], length 122: HTTP 03:05:34.781856 ens4 Out IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [.], ack 185, win 506, options [nop,nop,TS val 2475360892 ecr 1435446010], length 0 03:05:34.906503 ens4 Out IP 240.0.0.2.80 > 10.10.10.2.40326: Flags [P.], seq 1:265, ack 185, win 506, options [nop,nop,TS val 2475361016 ecr 1435446010], length 264: HTTP: HTTP/1.1 200 OK
17. クリーンアップ
Cloud Shell から、チュートリアルのコンポーネントを削除します。
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 dns record-sets delete class-e-vm.demo.com --zone=private-dns-codelab --type=A
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 networks delete consumer-vpc --quiet
18. 完了
お疲れさまでした。Vertex AI Pipelines で Private Service Connect インターフェースを構成して検証できました。
コンシューマー インフラストラクチャを作成し、プロデューサーがマルチ NIC VM を作成してコンシューマーとプロデューサーの通信をブリッジできるようにするネットワーク アタッチメントを追加しました。コンシューマー VPC ネットワークに明示的なプロキシをデプロイして、Vertex から直接ルーティングできない class-e-vm インスタンスへの接続を許可しながら、DNS ピアリングを作成する方法について説明しました。
Cosmopup はチュートリアルが大好きです。