Vertex AI Pipelines PSC 인터페이스 SWP

1. 소개

Private Service Connect 인터페이스는 프로듀서 가상 프라이빗 클라우드 (VPC) 네트워크가 소비자 VPC 네트워크의 다양한 대상에 연결을 시작할 수 있게 해주는 리소스입니다. 프로듀서 및 소비자 네트워크는 다른 프로젝트 및 조직에 포함될 수 있습니다.

네트워크 연결이 Private Service Connect 인터페이스의 연결을 수락하면 Google Cloud는 네트워크 연결에 지정된 소비자 서브넷의 IP 주소를 인터페이스에 할당합니다. 소비자 및 프로듀서 네트워크는 내부 IP 주소를 사용하여 연결되고 통신할 수 있습니다.

네트워크 연결과 Private Service Connect 인터페이스 간의 연결은 Private Service Connect 엔드포인트와 서비스 연결 간의 연결과 유사하지만 여기에는 두 가지 주요 차이점이 있습니다.

  • 네트워크 연결을 사용하면 프로듀서 네트워크가 소비자 네트워크 (관리형 서비스 이그레스)로의 연결을 시작할 수 있고, 엔드포인트를 사용하면 소비자 네트워크가 프로듀서 네트워크 (관리형 서비스 인그레스)에 대한 연결을 시작할 수 있습니다.
  • Private Service Connect 인터페이스 연결은 전환됩니다. 즉, 프로듀서 네트워크는 소비자 네트워크에 연결된 다른 네트워크와 통신할 수 있습니다.

d7dc28d6567e6283.png그림:1

Vertex AI PSC 인터페이스 도달 가능성 고려사항

  • Vertex AI PSC 인터페이스는 RFC1918 주소 블록 내의 VPC 또는 온프레미스에 있는 대상으로 트래픽을 라우팅할 수 있습니다.
  • 비RFC-1918 주소 블록을 타겟팅하는 PSC 인터페이스에는 RFC-1918 주소를 사용하여 소비자의 VPC에 배포된 명시적 프록시가 필요합니다. Vertex AI 배포 내에서 프록시는 대상 엔드포인트의 FQDN과 함께 정의되어야 합니다. 다음 비 RFC-1918 CIDR로의 라우팅을 용이하게 하기 위해 소비자 VPC에 구성된 명시적 프록시 모드 보안 웹 프록시 (SWP)를 나타내는 그림 1을 참고하세요.
  1. 240.0.0.0/4
  2. 203.0.113.0/24
  3. 10.10.20.0/28: 프록시가 필요하지 않으며 RFC-1918 범위에 속합니다.
  4. 인터넷 이그레스

Google 관리 테넌트 네트워크에 대한 인터넷 연결:

VPC-SC가 없는 Vertex AI PSC 인터페이스

  • PSC 인터페이스만 사용하여 배포를 구성하면 기본 인터넷 액세스가 유지됩니다. 이 아웃바운드 트래픽은 Google 관리 테넌트 네트워크에서 직접 나갑니다.

VPC-SC가 적용된 Vertex AI PSC 인터페이스

  • 프로젝트가 VPC 서비스 제어 경계에 속하는 경우 데이터 무단 반출이 방지되도록 경계에서 Google 관리 테넌트의 기본 인터넷 액세스를 차단합니다.
  • 이 시나리오에서 배포가 공용 인터넷에 액세스하도록 허용하려면 Vertex AI에 연결된 VPC를 통해 트래픽을 라우팅하는 보안 이그레스 경로를 명시적으로 구성해야 합니다. RFC 1918 주소가 있는 VPC 네트워크 내에 프록시 서버를 배포하고 Cloud NAT 게이트웨이와 페어링하는 것이 이를 달성하는 한 가지 방법입니다. 보안 웹 프록시를 사용하여 트래픽을 인터넷으로 전달할 수도 있습니다. 보안 웹 프록시를 만들면 Cloud NAT 게이트웨이가 자동으로 생성됩니다.

자세한 내용은 다음 리소스를 참고하세요.

Vertex AI 리소스에 대한 Private Service Connect 인터페이스 설정 | Google Cloud

빌드할 항목

이 튜토리얼에서는 그림 1에 표시된 대로 프로듀서에서 소비자의 컴퓨팅으로 연결할 수 있도록 Private Service Connect (PSC) 인터페이스를 사용하여 class-e-subnet의 RFC 1918이 아닌 엔드포인트를 타겟팅하는 포괄적인 Vertex AI Pipelines 배포를 빌드합니다.

2d095dc2f4de6b4b.png그림 2

DNS 피어링을 활용하여 Vertex AI Training을 호스팅하는 테넌트 프로젝트에서 소비자 VM을 확인하는 소비자 VPC에 단일 psc-network-attachment를 만들어 다음과 같은 사용 사례를 구현합니다.

Vertex AI Pipelines를 배포하고 명시적 프록시 모드에서 보안 웹 프록시를 구성하여 클래스 E 서브넷의 VM에 대해 wget를 실행할 수 있도록 합니다.

학습할 내용

  • 네트워크 연결을 만드는 방법
  • 프로듀서가 네트워크 연결을 사용하여 PSC 인터페이스를 만드는 방법
  • Google 관리 VPC 네트워크에서 소비자 VPC 네트워크에 구성된 비공개 도메인을 확인하기 위해 DNS 피어링을 설정하는 방법
  • Vertex AI PSC 인터페이스에서 보안 웹 프록시로 트래픽을 전달하는 방법
  • Vertex AI Pipelines에서 비 RFC-1918 IP 주소 공간으로 통신을 설정하는 방법

필요한 항목

Google Cloud 프로젝트

IAM 권한

2. 시작하기 전에

튜토리얼을 지원하도록 프로젝트 업데이트

이 튜토리얼에서는 Cloud Shell에서 gcloud 구성 구현을 지원하기 위해 $variables를 사용합니다.

Cloud Shell 내에서 다음을 실행합니다.

gcloud config list project
gcloud config set project [YOUR-PROJECT-ID]
projectid=YOUR-PROJECT-ID
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"
gcloud services enable "networkservices.googleapis.com"
gcloud services enable "networksecurity.googleapis.com"
gcloud services enable "certificatemanager.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 --enable-private-ip-google-access

프록시 전용 서브넷 만들기

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

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 \
--enable-private-ip-google-access

Cloud Router 및 NAT 구성

Google Cloud 보안 웹 프록시는 배포된 리전에서 Cloud NAT 게이트웨이와 연결된 Cloud Router를 자동으로 프로비저닝하고 관리합니다.

4. IAP 사용 설정

IAP (Identity Aware Proxy)가 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 \ 
    --private-network-ip=240.0.0.2

6. 보안 웹 프록시

Secure Web Proxy의 명시적 모드 (또는 명시적 프록시 라우팅 모드)는 클라이언트 워크로드가 SWP의 내부 IP 주소 또는 정규화된 도메인 이름과 포트를 전달 프록시로 사용하도록 명시적으로 구성해야 하는 배포 방법입니다.

아래 단계에서 YOUR-PROJECT-ID를 프로젝트 ID로 수정해야 합니다.

웹 프록시를 만듭니다.

Cloud Shell에서 텍스트 편집기를 사용하여 policy.yaml 파일을 만듭니다.

cat > policy.yaml << EOF
description: basic Secure Web Proxy policy
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1
EOF

Cloud Shell에서 보안 웹 프록시 정책을 생성합니다.

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

다음 섹션에서 호스트 sessionMatcher을 기반으로 class-e-vm에 대한 액세스를 허용하는 규칙을 만듭니다.

Cloud Shell에서 텍스트 편집기를 사용하여 rule1.yaml 파일을 만듭니다.

cat > rule1.yaml << EOF
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1/rules/allow-nonrfc-classe
description: Allow nonrfc class-e
enabled: true
priority: 1
basicProfile: ALLOW
sessionMatcher: host() == 'class-e-vm.demo.com'
EOF

다음 섹션에서 "class-e" VM에 apache2 설치를 허용하는 Jupyter 노트북 액세스를 허용하는 규칙을 만듭니다.

Cloud Shell에서 텍스트 편집기를 사용하여 rule2.yaml 파일을 만듭니다.

cat > rule2.yaml << EOF
name: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1/rules/allow-apache2
description: Allow Apache2 install on class-e VM
enabled: true
priority: 2
basicProfile: ALLOW
sessionMatcher: inIpRange(source.ip,'240.0.0.2')
EOF

Cloud Shell에서 보안 정책 규칙1을 생성합니다.

gcloud network-security gateway-security-policies rules import allow-nonrfc-classe \
    --source=rule1.yaml \
    --location=us-central1 \
    --gateway-security-policy=policy1

Cloud Shell에서 보안 정책 rule2를 생성합니다.

gcloud network-security gateway-security-policies rules import allow-apache2 \
    --source=rule2.yaml \
    --location=us-central1 \
    --gateway-security-policy=policy1

Vertex AI Training을 지원하려면 다음 설정으로 보안 웹 프록시 게이트웨이를 구성하세요.

  • 수신 포트: Vertex AI 애플리케이션의 코드 명시적 프록시 설정에 구성된 것과 동일한 포트를 사용합니다 (예: 8080).
  • 주소: RFC 1918 범위에서 비공개 IP 주소를 할당합니다.
  • 라우팅 모드: EXPLICIT_ROUTING_MODE로 설정합니다.

Cloud Shell에서 gateway.yaml 파일을 만들어 보안 웹 프록시 게이트웨이를 정의합니다.

cat > gateway.yaml << EOF
name: projects/$projectid/locations/us-central1/gateways/swp1
type: SECURE_WEB_GATEWAY
addresses: ["10.10.10.5"]
ports: [8080]
gatewaySecurityPolicy: projects/$projectid/locations/us-central1/gatewaySecurityPolicies/policy1
network: projects/$projectid/global/networks/consumer-vpc
subnetwork: projects/$projectid/regions/us-central1/subnetworks/rfc1918-subnet1
routingMode: EXPLICIT_ROUTING_MODE
EOF

Cloud Shell에서 보안 웹 프록시 인스턴스를 생성합니다.

gcloud network-services gateways import swp1 \
    --source=gateway.yaml \
    --location=us-central1

보안 웹 프록시를 배포하는 데 몇 분 정도 걸릴 수 있습니다.

e8a4cf23bfc63030.png

7. 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_MANUAL \
    --subnets=intf-subnet

참고: Vertex AI가 Google 관리 테넌트 프로젝트로 구성된 경우 이 첨부파일에서 승인된 프로젝트 ID를 명시적으로 언급하지 않아도 됩니다. '자동 수락'으로 구성된 것처럼 자동으로 추가됩니다.

네트워크 연결 나열

Cloud Shell에서 네트워크 연결을 나열합니다.

gcloud compute network-attachments list

네트워크 연결 설명

Cloud Shell 내에서 네트워크 연결을 설명합니다.

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

프로듀서가 Private Service Connect 인터페이스를 만들 때 사용할 PSC 네트워크 연결 이름(psc-network-attachment)을 기록해 둡니다.

Cloud 콘솔에서 PSC 네트워크 연결 URL을 보려면 다음으로 이동하세요.

네트워크 서비스 → Private Service Connect → 네트워크 연결 → psc-network-attachment

b969cca5242d9c8a.png

8. 비공개 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(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 내에서 보안 웹 프록시의 레코드 세트를 만들고 환경의 출력에 따라 IP 주소를 업데이트해야 합니다.

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

PSC 인터페이스에서 액세스를 허용하는 Cloud 방화벽 규칙 만들기

다음 섹션에서는 PSC 네트워크 연결에서 시작된 트래픽이 소비자 VPC의 RFC 1918 컴퓨팅 리소스에 액세스하도록 허용하는 방화벽 규칙을 만듭니다.

Cloud Shell에서 프록시 전용 서브넷에서 클래스 e 서브넷으로의 액세스를 허용하는 인그레스 방화벽 규칙을 만듭니다. SWP가 프록시 전용 서브넷을 소스 주소로 사용하여 연결을 시작합니다.

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.100.0/28" \
    --destination-ranges="240.0.0.0/4" \
    --enable-logging

9. Jupyter 노트북 만들기

다음 섹션에서는 Jupyter 노트북을 만드는 방법을 안내합니다. 이 노트북은 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"

스토리지 관리자 역할이 있는 서비스 계정을 업데이트합니다.

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

AI Platform 사용자 역할로 서비스 계정을 업데이트합니다.

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

역할 Artifact Registry 관리자로 서비스 계정을 업데이트합니다.

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

Cloud Build 편집자 역할이 있는 서비스 계정을 업데이트합니다.

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

노트북 서비스 계정이 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 내에서 비공개 클라이언트 인스턴스를 만듭니다.

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 콘솔의 Vertex AI로 이동하여 Vertex AI API가 사용 설정되어 있는지 확인하세요.

Cloud Shell 내부:

프로젝트 번호를 가져옵니다.

gcloud projects describe $projectid | grep projectNumber

프로젝트 번호를 설정합니다.

projectnumber=YOUR-PROJECT-NUMBER

AI Platform의 서비스 계정을 만듭니다. 프로젝트에 기존 서비스 계정이 있으면 이 단계를 건너뜁니다.

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

compute.networkAdmin 역할로 서비스 에이전트 계정을 업데이트합니다.

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

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"

storage.admin 역할로 기본 서비스 계정 업데이트

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

artifactregistry.admin 역할로 기본 서비스 계정 업데이트

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

12. 'class-e-vm'에 Apache2를 설치하고 Tcpdump를 사용 설정합니다.

class-e-vm에서 보안 웹 프록시를 통해 apache2를 설치합니다.

새 Cloud Shell 탭을 열고 프로젝트 변수를 업데이트하고 class-e-vm에 SSH로 연결합니다.

gcloud compute ssh --zone us-central1-a "class-e-vm" --tunnel-through-iap --project $projectid
sudo apt-get -o Acquire::http::Proxy="http://10.10.10.5:8080" update
sudo apt-get -o Acquire::http::Proxy="http://10.10.10.5:8080" install apache2 -y
sudo service apache2 restart
echo 'class-e Server !!' | sudo tee /var/www/html/index.html

보안 웹 프록시가 트래픽을 타겟으로 전달하는 데 사용하는 프록시 전용 서브넷에서 tcpdump 필터링을 실행합니다.

class-e-vm OS에서 proxy-vm 서브넷에 대해 필터링된 tcpdump를 실행합니다.

sudo tcpdump -i any net 10.10.100.0/24 -nn

참고: JupyterLab 세션을 열려면 워크벤치 튜토리얼 인스턴스 서브넷에서 비공개 Google 액세스를 사용 설정해야 합니다.

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 인스턴스에서 학습 작업을 실행합니다.

  1. Google Cloud 콘솔의 Vertex AI Workbench 페이지에서 인스턴스 탭으로 이동합니다.
  2. Vertex AI Workbench 인스턴스 이름 (workbench-tutorial) 옆에 있는 JupyterLab 열기를 클릭합니다. Vertex AI Workbench 인스턴스가 JupyterLab을 엽니다.
  3. 파일 > 새로 만들기 > 노트북을 선택합니다.
  4. 커널 > Python 3 선택

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://explicit-swp.demo.com:8080"
  • 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 nonRFC-1918 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://explicit-swp.demo.com:8080" # replace it with your Secure Web proxy Ip-address and the 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)를 사용하여 구성됩니다.
  • 여기서 명시적 라우팅 모드 웹 프록시는 explicit-swp.demo.com입니다. 변환은 소비자의 VPC 내에서 DNS 피어링을 통해 처리됩니다.
  • 포트 8080은 보안 웹 프록시에서 구성된 수신 대기 포트 (기본값)입니다.
  • wget에서 class-e-vm-demo.com으로의 변환은 DNS 피어링을 통해 이루어집니다.
  • 이 코드는 Vertex의 'psc-network-attachment'를 지정하여 네트워크 연결 서브넷을 활용하여 두 개의 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 = "explicit-swp.demo.com" #@param {type:"string"}
PROXY_VM_PORT = "8080" #@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로 끝나는 프로젝트 이름)를 선택합니다.

a2e0b6d6243f26f1.png

강조 표시된 필드는 PSC 네트워크 연결에서 Vertex AI Pipelines가 사용하는 IP 주소를 나타냅니다.

11e411ea919d3bad.png

15. Cloud Logging 유효성 검사

Vertex AI Pipelines 작업은 처음 실행하는 데 약 14분이 걸리며 이후 실행은 훨씬 짧습니다. 성공적인 결과를 검증하려면 다음을 실행하세요.

Vertex AI → 학습 → 커스텀 작업으로 이동합니다.

실행된 맞춤 작업 선택

2f467254aa0c2e3a.png

로그 보기를 선택합니다.

8d525d3b152bcc61.png

Cloud Logging을 사용할 수 있게 되면 강조 표시된 선택 항목을 생성하는 쿼리를 실행하여 Vertex AI Pipelines에서 class-e-vm로의 wget가 성공했음을 확인합니다.

a4f9e9167f4ce1ae.png

38972f834aa2bd1d.png

16. TCPDump 검증

컴퓨팅 인스턴스로의 연결을 추가로 검증하는 TCPDUMP 출력을 검토해 보겠습니다.

class-e-vm에서 HTTP GET 및 200 OK를 관찰합니다.

XXXXXXXXX@class-e-vm:~$ sudo tcpdump -i any net 10.10.100.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
05:51:14.173641 ens4  In  IP 10.10.100.8.55306 > 240.0.0.2.80: Flags [S], seq 1747181041, win 65535, options [mss 1420,sackOK,TS val 3942828403 ecr 0,nop,wscale 8], length 0
05:51:14.173668 ens4  Out IP 240.0.0.2.80 > 10.10.100.8.55306: Flags [S.], seq 3013226100, ack 1747181042, win 64768, options [mss 1420,sackOK,TS val 1886125065 ecr 3942828403,nop,wscale 7], length 0
05:51:14.174977 ens4  In  IP 10.10.100.8.55306 > 240.0.0.2.80: Flags [.], ack 1, win 1054, options [nop,nop,TS val 3942828405 ecr 1886125065], length 0
05:51:14.175066 ens4  In  IP 10.10.100.8.55306 > 240.0.0.2.80: Flags [P.], seq 1:223, ack 1, win 1054, options [nop,nop,TS val 3942828405 ecr 1886125065], length 222: HTTP: GET / HTTP/1.1
05:51:14.175096 ens4  Out IP 240.0.0.2.80 > 10.10.100.8.55306: Flags [.], ack 223, win 505, options [nop,nop,TS val 1886125066 ecr 3942828405], length 0
05:51:14.239042 ens4  Out IP 240.0.0.2.80 > 10.10.100.8.55306: Flags [P.], seq 1:246, ack 223, win 505, options [nop,nop,TS val 1886125130 ecr 3942828405], length 245: HTTP: HTTP/1.1 200 OK

17. 삭제

Cloud Shell에서 튜토리얼 구성요소를 삭제합니다.

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

gcloud network-security gateway-security-policies rules delete allow-nonrfc-classe \
    --gateway-security-policy=policy1 \
    --location=us-central1

gcloud network-security gateway-security-policies rules delete allow-apache2 \
    --gateway-security-policy=policy1 \
    --location=us-central1

gcloud network-security gateway-security-policies delete policy1 \
    --location=us-central1
gcloud network-services gateways delete swp1 \
    --location=us-central1

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 explicit-swp.demo.com --zone=private-dns-codelab  --type=A

gcloud dns managed-zones delete private-dns-codelab

gcloud computeinstances delete class-e-vm --project=$projectid --zone=us-central1-a --quiet
gcloud compute networks delete consumer-vpc --quiet

18. 축하합니다

축하합니다. 보안 웹 프록시를 통해 Vertex AI Pipelines Private Service Connect 인터페이스와 RFC가 아닌 IP 범위 간의 연결을 구성하고 검증했습니다.

소비자 인프라를 만들고 프로듀서가 소비자 및 프로듀서 커뮤니케이션을 연결하는 다중 NIC VM을 만들 수 있도록 네트워크 연결을 추가했습니다. Vertex에서 직접 라우팅할 수 없는 class-e-vm 인스턴스에 연결할 수 있는 소비자 VPC 네트워크에 명시적 프록시를 배포하는 동안 DNS 피어링을 만드는 방법을 알아봤습니다.

678ba30d64a76795.png

다음 단계

추가 자료 및 동영상

참조 문서