Private Service Connect - การใช้แบ็กเอนด์ PSC เพื่อเข้าถึง Google API ระดับภูมิภาค

1. บทนำ

Private Service Connect เป็นความสามารถของเครือข่าย Google Cloud ที่ช่วยให้ผู้บริโภคเข้าถึงบริการของผู้ผลิตได้ ซึ่งรวมถึงความสามารถในการเชื่อมต่อกับ Google API ผ่านปลายทางส่วนตัวที่โฮสต์ภายใน VPC ของผู้ใช้(โดยทั่วไปคือผู้บริโภค)

นอกจากนี้ คุณยังใช้แบ็กเอนด์ PSC ร่วมกับตัวจัดสรรภาระงานพร็อกซีของ Google Cloud เพื่อชี้ไปยัง Google API เฉพาะภูมิภาคได้ด้วย การใช้แบ็กเอนด์ PSC จะช่วยให้ควบคุมฝั่งผู้บริโภคได้ละเอียดยิ่งขึ้น เช่น

  • การเลือกบริการ Google API ที่พร้อมใช้งานโดยใช้ URL Map
  • ความสามารถในการสังเกตที่ละเอียดยิ่งขึ้น
  • การผสานรวม Cloud Armor
  • URL ที่กำหนดเอง
  • การจัดการการรับส่งข้อมูลขั้นสูง

ดูรายการบริการที่พร้อมให้บริการและ API ระดับภูมิภาคได้ที่นี่

ใน Codelab นี้ คุณจะสร้างแบ็กเอนด์ PSC ที่ชี้ไปยัง Cloud KMS API ระดับภูมิภาคและทดสอบการเชื่อมต่อกับ API นั้น

สิ่งที่คุณจะได้เรียนรู้

  • สร้างคีย์ริงและคีย์ Cloud Key Management Service (KMS)
  • สร้างตัวจัดสรรภาระงานของแอปพลิเคชันภายในที่มีแบ็กเอนด์ PSC ซึ่งชี้ไปยัง API ระดับภูมิภาคของ Cloud KMS
  • การสร้างโซนส่วนตัวที่มีการจัดการของ Cloud DNS และระเบียน A
  • เข้าถึง Cloud KMS ระดับภูมิภาค

สิ่งที่คุณต้องมี

  • โปรเจ็กต์ Google Cloud ที่มีสิทธิ์ "เจ้าของ" หรือ "ผู้แก้ไข" แบบเต็ม

2. โทโพโลยี Codelab

1a18ae253213e215.png

ระบบจะสร้าง VPC ของผู้ใช้ที่มีซับเน็ต 1 รายการในภูมิภาค europe-west9 สำหรับโฮสต์ VM, กฎการส่งต่อของตัวจัดสรรภาระงานของแอปพลิเคชันระดับภูมิภาคภายใน และแบ็กเอนด์ PSC รวมถึงซับเน็ตเฉพาะพร็อกซี 1 รายการสำหรับใช้กับตัวจัดสรรภาระงาน เราจะสร้างคีย์ริงและคีย์ใน Cloud Key Management System (KMS) ในภูมิภาคยุโรปตะวันตก จากนั้นเราจะสร้างตัวจัดสรรภาระงานและแบ็กเอนด์ PSC เพื่อแก้ไขไปยัง KMS API ระดับภูมิภาคใน europe-west9

3. การตั้งค่าและข้อกำหนด

การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง

  1. ลงชื่อเข้าใช้ Google Cloud Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ คุณอัปเดตได้ทุกเมื่อ
  • รหัสโปรเจ็กต์จะไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและเปลี่ยนแปลงไม่ได้ (เปลี่ยนไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยทั่วไปจะระบุเป็น PROJECT_ID) หากไม่ชอบรหัสที่สร้างขึ้น คุณอาจสร้างรหัสแบบสุ่มอีกรหัสหนึ่งได้ หรือคุณอาจลองใช้ชื่อของคุณเองและดูว่ามีชื่อนั้นหรือไม่ คุณจะเปลี่ยนแปลงรหัสนี้หลังจากขั้นตอนนี้ไม่ได้ และรหัสจะคงอยู่ตลอดระยะเวลาของโปรเจ็กต์
  • โปรดทราบว่ายังมีค่าที่ 3 ซึ่งคือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 นี้ได้ในเอกสารประกอบ
  1. จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การทำตาม Codelab นี้จะไม่มีค่าใช้จ่ายมากนัก หรืออาจไม่มีค่าใช้จ่ายเลย หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่สร้างขึ้นหรือลบโปรเจ็กต์ได้ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD

เริ่มต้น Cloud Shell

แม้ว่าคุณจะใช้งาน Google Cloud จากระยะไกลจากแล็ปท็อปได้ แต่ใน Codelab นี้คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์

จาก Google Cloud Console ให้คลิกไอคอน Cloud Shell ในแถบเครื่องมือด้านขวาบน

55efc1aaa7a4d3ad.png

การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมจะใช้เวลาเพียงไม่กี่นาที เมื่อเสร็จแล้ว คุณควรเห็นข้อความคล้ายกับตัวอย่างต่อไปนี้

7ffe5cbb04455448.png

เครื่องเสมือนนี้มาพร้อมเครื่องมือพัฒนาซอฟต์แวร์ทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักแบบถาวรขนาด 5 GB และทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก คุณสามารถทำงานทั้งหมดใน Codelab นี้ได้ภายในเบราว์เซอร์ คุณไม่จำเป็นต้องติดตั้งอะไร

4. ก่อนเริ่มต้น

เปิดใช้ API

ตรวจสอบว่าได้ตั้งค่ารหัสโปรเจ็กต์ใน Cloud Shell แล้ว

gcloud config list project
gcloud config set project <project-id>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=europe-west9
export ZONE=europe-west9-a
echo $PROJECT_ID
echo $REGION
echo $ZONE

เปิดใช้บริการทั้งหมดที่จำเป็น

gcloud services enable compute.googleapis.com
gcloud services enable servicedirectory.googleapis.com
gcloud services enable dns.googleapis.com
gcloud services enable cloudkms.googleapis.com

5. สร้างเครือข่าย VPC, ซับเน็ต และกฎไฟร์วอลล์

สร้างเครือข่าย VPC

จาก Cloud Shell

# Set environment variables

export VPC_NAME="consumer-vpc"
export SUBNET_NAME="consumer-subnet-1"

# Create VPC network

gcloud compute networks create ${VPC_NAME} \
    --subnet-mode=custom \
    --bgp-routing-mode=regional

สร้างซับเน็ต

จาก Cloud Shell

gcloud compute networks subnets create ${SUBNET_NAME} \
    --network=${VPC_NAME} \
    --region=${REGION} \
    --range=10.0.0.0/24 \
    --enable-private-ip-google-access

ใน Lab นี้ คุณจะสร้างตัวจัดสรรภาระงานระดับภูมิภาค L7 ภายในเพื่อชี้ไปยังแบ็กเอนด์ API ระดับภูมิภาค ตัวจัดสรรภาระงานนี้เป็นตัวจัดสรรภาระงานพร็อกซี ดังนั้นคุณต้องสร้าง "ซับเน็ตพร็อกซี" ที่มีไว้สำหรับตัวจัดสรรภาระงานเพื่อทำหน้าที่เป็นพร็อกซี ดูข้อมูลเพิ่มเติมเกี่ยวกับซับเน็ตเฉพาะพร็อกซีได้ที่นี่

จาก Cloud Shell

gcloud compute networks subnets create eu-west9-proxy-subnet \
--network=${VPC_NAME} \
--region=${REGION} \
--range=10.100.100.0/24 \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE

สร้างกฎไฟร์วอลล์

สำหรับแล็บนี้ คุณจะใช้ IAP เพื่อเชื่อมต่อกับอินสแตนซ์ที่สร้างขึ้น หากไม่ต้องการใช้ IAP คุณสามารถข้ามขั้นตอนนี้ และเพิ่มที่อยู่ IP สาธารณะในอินสแตนซ์แทน แล้วสร้างกฎไฟร์วอลล์ที่อนุญาตให้ใช้ข้อมูลขาเข้าบนพอร์ต TCP 22 จาก 0.0.0.0/0

หากต้องการอนุญาตให้ IAP เชื่อมต่อกับอินสแตนซ์ VM ให้สร้างกฎไฟร์วอลล์ที่มีลักษณะดังนี้

  • มีผลกับอินสแตนซ์ VM ทั้งหมดที่คุณต้องการให้เข้าถึงได้โดยใช้ IAP
  • อนุญาตการรับส่งข้อมูลขาเข้าจากช่วง IP 35.235.240.0/20 ช่วงนี้มีที่อยู่ IP ทั้งหมดที่ IAP ใช้สำหรับการส่งต่อ TCP

จาก Cloud Shell

gcloud compute firewall-rules create allow-ssh-iap \
    --network=${VPC_NAME} \
--allow tcp:22 \
--source-ranges=35.235.240.0/20

6. สร้าง Cloud NAT

ต้องสร้าง Cloud NAT เพื่อดาวน์โหลดการกระจายแพ็กเกจ Linux

สร้าง Cloud Router

จาก Cloud Shell

gcloud compute routers create crnat \
    --network=${VPC_NAME} \
    --region=${REGION}

สร้าง Cloud NAT

จาก Cloud Shell

gcloud compute routers nats create europe-nat \
    --router=crnat \
    --auto-allocate-nat-external-ips \
    --nat-all-subnet-ip-ranges \
    --enable-logging \
    --region=${REGION}

7. สร้างคีย์ริงและคีย์การจัดการคีย์

จาก Cloud Shell

gcloud kms keyrings create europe-kr \
    --location ${REGION}

จาก Cloud Shell

gcloud kms keys create europe-key \
    --location ${REGION} \
    --keyring europe-kr \
    --purpose encryption

จาก Cloud Shell ให้ยืนยันว่าสร้างพวงกุญแจและคีย์ในภูมิภาคยุโรปตะวันตกเรียบร้อยแล้ว

gcloud kms keys list \
    --location ${REGION} \
    --keyring europe-kr

ผลลัพธ์ที่คาดหวัง

NAME: projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key
PURPOSE: ENCRYPT_DECRYPT
ALGORITHM: GOOGLE_SYMMETRIC_ENCRYPTION
PROTECTION_LEVEL: SOFTWARE
LABELS: 
PRIMARY_ID: 1
PRIMARY_STATE: ENABLED

จดชื่อเส้นทางแบบเต็มที่กำหนดให้กับคีย์ไว้ เนื่องจากคุณจะต้องใช้ชื่อนี้เพื่อเชื่อมต่อในภายหลัง

8. สร้าง VM ไคลเอ็นต์และเชื่อมต่อกับ KMS API

จากนั้นคุณจะสร้าง VM ไคลเอ็นต์, SSH ไปยัง VM และทดสอบการแก้ไข API ของ KMS ทั่วโลก การทดสอบนี้แสดงถึงตัวเลือกเริ่มต้นสำหรับการแก้ไขปัญหา Google API ทั่วโลก

จาก Cloud Shell

#Create the startup script

touch startup.sh

#Open the startup.sh file using a text editor of your choice (e.g., nano, vim, gedit, etc.)

nano startup.sh 

#Paste the following script content into the startup.sh file

#! /bin/bash 
sudo apt-get update 
sudo apt-get install dnsutils -y 
sudo apt-get install tcpdump -y

#Save the changes you made to the startup.sh file
#Use the chmod command to make the script executable

chmod +x startup.sh

#Create the VM instance

gcloud compute instances create client-vm \
    --network="${VPC_NAME}" \
    --subnet="${SUBNET_NAME}" \
    --zone="europe-west9-a" \
    --machine-type="e2-medium" \
    --no-address \
    --scopes="https://www.googleapis.com/auth/cloud-platform" \
    --image-family="debian-12" \
    --image-project="debian-cloud" \
    --metadata-from-file="startup-script=./startup.sh" 

จากนั้นคุณจะต้องอัปเดตบัญชีบริการ Compute เริ่มต้นเพื่อให้มีสิทธิ์เข้าถึงคีย์ KMS ที่คุณสร้างขึ้น บัญชีบริการ Compute เริ่มต้นจะมีรูปแบบเป็น <หมายเลขโปรเจ็กต์> -compute@developer.gserviceaccount.com หากต้องการดูหมายเลขโปรเจ็กต์ ให้เรียกใช้คำสั่งต่อไปนี้จาก Cloud Shell แล้วคัดลอกหมายเลขในบรรทัดสุดท้ายของผลลัพธ์ที่แสดง

 gcloud projects describe $PROJECT_ID

อัปเดตบัญชีบริการ Compute เริ่มต้นเพื่อให้มีสิทธิ์เข้าถึงคีย์ KMS ที่คุณสร้างขึ้น

จาก Cloud Shell

gcloud kms keys add-iam-policy-binding europe-key \
    --location $REGION \
    --keyring europe-kr \
    --member serviceAccount:<project_number>-compute@developer.gserviceaccount.com \
    --role roles/cloudkms.admin

สร้างเทอร์มินัล Cloud Shell เพิ่มเติมโดยคลิก + (ภาพหน้าจอด้านล่าง)

a36edc967333315a.png

ในแท็บ 2 ให้สร้างอุโมงค์ผ่าน IAP เพื่อ SSH ไปยัง client-vm โปรดทราบว่าตัวแปรสภาพแวดล้อมจะไม่ได้รับการโอน และคุณจะต้องเพิ่ม project-id ลงในคำสั่งด้านล่าง

จาก Cloud Shell

# Set the environment variable

export PROJECT_ID=$(gcloud config get-value project)

# ssh into the client-vm

gcloud beta compute ssh --zone europe-west9-a "client-vm" \
--tunnel-through-iap \
--project $PROJECT_ID

เชื่อมต่อกับ Global KMS API โดยใช้ชื่อคีย์ KMS ที่คุณจดไว้ก่อนหน้านี้

จากแท็บ 2, client-vm

# Store the access token in a variable

TOKEN=$(gcloud auth print-access-token)

# Run the full command with maximum verbosity
curl -v \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
'https://cloudkms.googleapis.com/v1/projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key'

ผลลัพธ์ที่คาดหวัง

*   Trying 216.58.214.74:443...
* Connected to cloudkms.googleapis.com (216.58.214.74) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=upload.video.google.com
*  start date: Aug 26 07:12:45 2024 GMT
*  expire date: Nov 18 07:12:44 2024 GMT
*  subjectAltName: host "cloudkms.googleapis.com" matched cert's "*.googleapis.com"
*  issuer: C=US; O=Google Trust Services; CN=WR2
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /v1/projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key]
* h2h3 [:scheme: https]
* h2h3 [:authority: cloudkms.googleapis.com]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* h2h3 [authorization: Bearer dsnkjfdnvjfd
* h2h3 [content-type: application/json]
* Using Stream ID: 1 (easy handle 0x55ed8bb7ece0)
> GET /v1/projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key HTTP/2
> Host: cloudkms.googleapis.com
> user-agent: curl/7.88.1
> accept: */*
> authorization: Bearer dsnkjfdnvjfd
> content-type: application/json
>
< HTTP/2 200
< content-type: application/json; charset=UTF-8
< vary: X-Origin
< vary: Referer
< vary: Origin,Accept-Encoding
< date: Tue, 24 Sep 2024 18:25:42 GMT
< server: ESF
< cache-control: private
< x-xss-protection: 0
< x-frame-options: SAMEORIGIN
< x-content-type-options: nosniff
< accept-ranges: none
<
{
  "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key",
  "primary": {
    "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key/cryptoKeyVersions/1",
    "state": "ENABLED",
    "createTime": "2024-09-24T17:56:01.905156045Z",
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION",
    "generateTime": "2024-09-24T17:56:01.905156045Z"
  },
  "purpose": "ENCRYPT_DECRYPT",
  "createTime": "2024-09-24T17:56:01.905156045Z",
  "versionTemplate": {
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION"
  },
  "destroyScheduledDuration": "2592000s"
}
* Connection #0 to host cloudkms.googleapis.com left intact

ตรวจสอบว่า DNS จะจับคู่ข้อมูลปลายทาง KMS กับที่ใด

จากแท็บ 2, client-vm

dig cloudkms.googleapis.com

ผลลัพธ์ที่คาดหวัง

 <<>> DiG 9.18.28-1~deb12u2-Debian <<>> cloudkms.googleapis.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62617
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;cloudkms.googleapis.com.       IN      A

;; ANSWER SECTION:
cloudkms.googleapis.com. 300    IN      A       142.250.74.234
cloudkms.googleapis.com. 300    IN      A       142.250.75.234
cloudkms.googleapis.com. 300    IN      A       216.58.214.170
cloudkms.googleapis.com. 300    IN      A       172.217.20.170
cloudkms.googleapis.com. 300    IN      A       172.217.20.202
cloudkms.googleapis.com. 300    IN      A       216.58.215.42
cloudkms.googleapis.com. 300    IN      A       216.58.213.74
cloudkms.googleapis.com. 300    IN      A       142.250.179.74
cloudkms.googleapis.com. 300    IN      A       142.250.179.106
cloudkms.googleapis.com. 300    IN      A       142.250.178.138
cloudkms.googleapis.com. 300    IN      A       142.250.201.170
cloudkms.googleapis.com. 300    IN      A       172.217.18.202
cloudkms.googleapis.com. 300    IN      A       216.58.214.74

;; Query time: 4 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Wed Oct 23 19:58:58 UTC 2024
;; MSG SIZE  rcvd: 260

จากแท็บ 2, client-vm

dig cloudkms.europe-west9.rep.googleapis.com

ผลลัพธ์ที่คาดหวัง

<<>> DiG 9.18.28-1~deb12u2-Debian <<>> cloudkms.europe-west9.rep.googleapis.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2736
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;cloudkms.europe-west9.rep.googleapis.com. IN A

;; ANSWER SECTION:
cloudkms.europe-west9.rep.googleapis.com. 3043 IN A 34.1.65.232

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Wed Oct 23 20:00:04 UTC 2024
;; MSG SIZE  rcvd: 85

ลักษณะการทำงานเริ่มต้นสำหรับ Google APIs คือการใช้ปลายทางบริการ Global API ปลายทางนี้จะเปลี่ยนเป็นรายการ IP สาธารณะ คำสั่ง dig สำหรับ cloudkms.googleapis.com แสดงสิ่งนี้ (หมายเหตุ: ที่อยู่ IP ที่คุณเห็นอาจเป็นที่อยู่ IP ภายนอกอื่น ซึ่งเป็นลักษณะการทำงานปกติของ Google APIs)

การใช้ปลายทาง Google API ระดับภูมิภาคกับ PSC ช่วยให้คุณปฏิบัติตามข้อกำหนดระดับภูมิภาคสำหรับการเข้าชม API รวมถึงเปลี่ยนความละเอียดจากสาธารณะเป็นส่วนตัวได้ การใช้คำสั่ง dig กับ cloudkms.europe-west9.rep.googleapis.com แสดงให้เห็นว่าในตอนนี้ การแปลค่าไปยังปลายทาง API ของ KSM ระดับภูมิภาคยังคงเป็นแบบสาธารณะ

ในส่วนต่อไปนี้ เราจะย้ายข้อมูลจากการใช้ปลายทาง Global KMS API ไปยังปลายทางระดับภูมิภาค และเปลี่ยนความละเอียดเป็นส่วนตัวโดยใช้แบ็กเอนด์ PSC

9. สร้าง NEG และตัวจัดสรรภาระงาน PSC

สำหรับส่วนถัดไป ให้กลับไปที่แท็บแรกใน Cloud Shell

คุณจะสร้างตัวจัดสรรภาระงาน HTTP(S) ภายในที่มีกลุ่มปลายทางเครือข่าย(NEG) ซึ่งชี้ไปยังปลายทาง KMS ระดับภูมิภาคของยุโรปเป็นบริการแบ็กเอนด์ กฎการส่งต่อของตัวจัดสรรภาระงานจะทำหน้าที่เป็นปลายทาง Private Service Connect(PSC)

สร้างกลุ่มปลายทางเครือข่าย (NEG) ที่มีประเภท Private Service Connect และบริการเป้าหมาย europe-west9-cloudkms.example.com

จาก Cloud Shell

#Set the necessary variables

NEG_NAME="l7psc-kms-neg"
PSC_TARGET="cloudkms.europe-west9.rep.googleapis.com"

#Create the Private Service Connect NEG

gcloud compute network-endpoint-groups create ${NEG_NAME} \
    --project=${PROJECT_ID} \
    --region=${REGION} \
    --network-endpoint-type=PRIVATE_SERVICE_CONNECT \
    --psc-target-service=${PSC_TARGET}

# Verify the NEG creation

gcloud compute network-endpoint-groups describe ${NEG_NAME} \
    --project=${PROJECT_ID} \
    --region=${REGION}

สร้างบริการแบ็กเอนด์สำหรับตัวจัดสรรภาระงาน

จาก Cloud Shell

# 1. Set the necessary variables

BACKEND_SERVICE_NAME="l7-psc-kms"

# 2. Create the backend service

gcloud compute backend-services create $BACKEND_SERVICE_NAME \
  --load-balancing-scheme=INTERNAL_MANAGED \
  --protocol=HTTPS \
  --region=$REGION \

เพิ่ม NEG ลงในบริการแบ็กเอนด์

จาก Cloud Shell

gcloud compute backend-services add-backend $BACKEND_SERVICE_NAME \
  --network-endpoint-group=${NEG_NAME} \
  --region=$REGION

สร้างแมป URL สำหรับตัวจัดสรรภาระงาน

จาก Cloud Shell

gcloud compute url-maps create l7-psc-url-map \
  --default-service=l7-psc-kms \
  --region=$REGION

สร้างตัวเทียบเส้นทางสำหรับ URL ที่กำหนดเองซึ่งปลายทางจะใช้

จาก Cloud Shell

gcloud compute url-maps add-path-matcher l7-psc-url-map \
 --path-matcher-name=example \
 --default-service=l7-psc-kms \
 --region=$REGION

สร้างกฎโฮสต์สำหรับ URL ที่กำหนดเอง europe-west9-cloudkms.example.com

จาก Cloud Shell

gcloud compute url-maps add-host-rule l7-psc-url-map \
--hosts=europe-west9-cloudkms.example.com \
--path-matcher-name=example \
--region=$REGION

สร้างพร็อกซี HTTPS เป้าหมายสำหรับตัวจัดสรรภาระงาน โดยคุณต้องสร้างทรัพยากรใบรับรอง SSL ระดับภูมิภาค ดูขั้นตอนการสร้างใบรับรองแบบ Self-signed ได้ที่นี่ เราจะสร้างใบรับรองที่ลงนามด้วยตนเองโดยใช้ openssl และใช้ใบรับรองดังกล่าวเพื่อสร้างทรัพยากรใบรับรองระดับภูมิภาคใน GCP พร็อกซี HTTPS เป้าหมายจะใช้ใบรับรองนี้

จาก Cloud Shell

# Set environment variables

export CERT_NAME="my-ssl-cert"

# Generate a private key

openssl genrsa -out private.key 2048

#  Create a configuration file for the CSR

cat > csr_config.cnf << EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[dn]
CN = example.com
O = My Organization
C = US

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = example.com
DNS.2 = *.example.com
EOF

# Create a CSR using the configuration

openssl req -new -key private.key -out server.csr -config csr_config.cnf

# Create a self-signed certificate using the CSR

openssl x509 -req -days 365 -in server.csr -signkey private.key -out server.crt \
    -extfile csr_config.cnf -extensions req_ext

# Verify the certificate

openssl x509 -in server.crt -text -noout

#Create a regional SSL certificate resource 

gcloud compute ssl-certificates create ${CERT_NAME} \
    --region=${REGION} \
    --certificate=server.crt \
    --private-key=private.key

#Create the target HTTPS proxy for the load balancer 

gcloud compute target-https-proxies create psc-http-proxy \
    --region=${REGION} \
    --url-map=l7-psc-url-map \
    --ssl-certificates=${CERT_NAME}

สร้างกฎการส่งต่อสำหรับตัวจัดสรรภาระงานที่จะทำหน้าที่เป็นปลายทาง Private Service Connect ที่อยู่ IP สำหรับกฎการส่งต่อต้องอยู่ในซับเน็ตระดับภูมิภาคใน VPC ที่อยู่ในภูมิภาคเดียวกับปลายทาง API ที่คุณกำลังเข้าถึง

จาก Cloud Shell

# Set environment variables

export PROXY_NAME="psc-http-proxy"

# Create the forwarding rule

gcloud compute forwarding-rules create kms-lb-rule \
    --project=${PROJECT_ID} \
    --region=${REGION} \
    --load-balancing-scheme=INTERNAL_MANAGED \
    --network=${VPC_NAME} \
    --subnet=${SUBNET_NAME} \
    --target-https-proxy=${PROXY_NAME} \
    --target-https-proxy-region=${REGION} \
    --address=10.0.0.100 \
    --ports=443

10. การกำหนดค่า DNS

ในส่วนนี้ คุณจะสร้างโซน DNS ส่วนตัวสำหรับ example.com และระเบียน A ที่ชี้ไปยังกฎการส่งต่อที่เราสร้างขึ้นในขั้นตอนสุดท้าย

สร้างโซนส่วนตัวของ DNS ที่มีการจัดการ

จาก Cloud Shell

# Set environment variables

export LB_RULE_NAME="kms-lb-rule"
export DNS_ZONE_NAME="example-com-private-zone"

# Create the private DNS zone

gcloud dns managed-zones create ${DNS_ZONE_NAME} \
    --dns-name="example.com." \
    --description="Private DNS zone for example.com" \
    --visibility=private \
    --networks=${VPC_NAME}

สร้างระเบียน A สำหรับ europe-west9-cloudkms.example.com

จาก Cloud Shell

gcloud dns record-sets transaction start \
   --zone=${DNS_ZONE_NAME}

gcloud dns record-sets transaction add 10.0.0.100 \
   --name=europe-west9-cloudkms.example.com \
   --ttl=300 \
   --type=A \
   --zone=${DNS_ZONE_NAME}

gcloud dns record-sets transaction execute \
   --zone=${DNS_ZONE_NAME}

11. เชื่อมต่อกับ Regional KMS API ผ่าน PSC

เปลี่ยนกลับไปที่ client-vm ในแท็บ 2 เพื่อเรียกใช้ tcpdump เพื่อดูรายละเอียดการเชื่อมต่อทั้งหมดและทดสอบการเชื่อมต่อกับปลายทาง KMS ระดับภูมิภาคผ่านแบ็กเอนด์ PSC

sudo tcpdump -i any net 10.0.0.100 or port 53 -n

เปิดแท็บที่ 3 ใน Cloud Shell แล้ว SSH ไปยัง client-vm

# Set environment variables

export PROJECT_ID=$(gcloud config get-value project)
export KMS_HOSTNAME="europe-west9-cloudkms.example.com"
export KEY_RING="europe-kr"
export KEY_NAME="europe-key"
export REGION="europe-west9"

# Command to access the specific key

curl -k "https://${KMS_HOSTNAME}/v1/projects/${PROJECT_ID}/locations/${REGION}/keyRings/${KEY_RING}/cryptoKeys/${KEY_NAME}" \
  -H "Authorization: Bearer $(gcloud auth print-access-token)"

ผลลัพธ์ที่คาดไว้สำหรับคำสั่ง curl + TCPDUMP

{
  "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key",
  "primary": {
    "name": "projects/<project-id>/locations/europe-west9/keyRings/europe-kr/cryptoKeys/europe-key/cryptoKeyVersions/1",
    "state": "ENABLED",
    "createTime": "2024-10-10T18:50:24.357027036Z",
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION",
    "generateTime": "2024-10-10T18:50:24.357027036Z"
  },
  "purpose": "ENCRYPT_DECRYPT",
  "createTime": "2024-10-10T18:50:24.357027036Z",
  "versionTemplate": {
    "protectionLevel": "SOFTWARE",
    "algorithm": "GOOGLE_SYMMETRIC_ENCRYPTION"
  },
  "destroyScheduledDuration": "2592000s"
}


Tcpdump output

listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
18:13:51.220209 lo    In  IP 127.0.0.1.48873 > 127.0.0.53.53: 2086+ [1au] A? europe-west9-cloudkms.example.com. (62)
18:13:51.220230 lo    In  IP 127.0.0.1.48873 > 127.0.0.53.53: 24619+ [1au] AAAA? europe-west9-cloudkms.example.com. (62)
18:13:51.220669 ens4  Out IP 10.0.0.2.52121 > 169.254.169.254.53: 8885+ [1au] A? europe-west9-cloudkms.example.com. (62)
18:13:51.220784 ens4  Out IP 10.0.0.2.53041 > 169.254.169.254.53: 57748+ [1au] AAAA? europe-west9-cloudkms.example.com. (62)
18:13:51.229638 ens4  In  IP 169.254.169.254.53 > 10.0.0.2.52121: 8885 1/0/1 A 10.0.0.100 (78)
18:13:51.229945 lo    In  IP 127.0.0.53.53 > 127.0.0.1.48873: 2086 1/0/1 A 10.0.0.100 (78)
18:13:51.230068 ens4  In  IP 169.254.169.254.53 > 10.0.0.2.53041: 57748 0/1/1 (155)
18:13:51.230203 lo    In  IP 127.0.0.53.53 > 127.0.0.1.48873: 24619 0/1/1 (155)
18:13:51.230390 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [S], seq 1606150798, win 65320, options [mss 1420,sackOK,TS val 4135800856 ecr 0,nop,wscale 7], length 0
18:13:51.232565 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [S.], seq 1041507402, ack 1606150799, win 65535, options [mss 1420,sackOK,TS val 2276748382 ecr 4135800856,nop,wscale 8], length 0
18:13:51.232583 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [.], ack 1, win 511, options [nop,nop,TS val 4135800859 ecr 2276748382], length 0
18:13:51.235494 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 1:518, ack 1, win 511, options [nop,nop,TS val 4135800862 ecr 2276748382], length 517
18:13:51.236571 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [.], ack 518, win 267, options [nop,nop,TS val 2276748387 ecr 4135800862], length 0
18:13:51.239119 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 1:1356, ack 518, win 267, options [nop,nop,TS val 2276748389 ecr 4135800862], length 1355
18:13:51.239140 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [.], ack 1356, win 501, options [nop,nop,TS val 4135800865 ecr 2276748389], length 0
18:13:51.240978 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 518:598, ack 1356, win 501, options [nop,nop,TS val 4135800867 ecr 2276748389], length 80
18:13:51.241266 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 598:684, ack 1356, win 501, options [nop,nop,TS val 4135800867 ecr 2276748389], length 86
18:13:51.241366 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 684:1646, ack 1356, win 501, options [nop,nop,TS val 4135800867 ecr 2276748389], length 962
18:13:51.242370 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [.], ack 684, win 267, options [nop,nop,TS val 2276748392 ecr 4135800867], length 0
18:13:51.242619 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 1356:1433, ack 1646, win 278, options [nop,nop,TS val 2276748393 ecr 4135800867], length 77
18:13:51.242730 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [P.], seq 1646:1677, ack 1433, win 501, options [nop,nop,TS val 4135800869 ecr 2276748393], length 31
18:13:51.248724 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [.], ack 1677, win 278, options [nop,nop,TS val 2276748399 ecr 4135800869], length 0
18:13:51.296676 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 1433:2357, ack 1677, win 278, options [nop,nop,TS val 2276748447 ecr 4135800869], length 924
18:13:51.297223 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [F.], seq 1677, ack 2357, win 501, options [nop,nop,TS val 4135800923 ecr 2276748447], length 0
18:13:51.298304 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [P.], seq 2357:2381, ack 1678, win 278, options [nop,nop,TS val 2276748448 ecr 4135800923], length 24
18:13:51.298305 ens4  In  IP 10.0.0.100.443 > 10.0.0.2.59474: Flags [F.], seq 2381, ack 1678, win 278, options [nop,nop,TS val 2276748448 ecr 4135800923], length 0
18:13:51.298336 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [R], seq 1606152476, win 0, length 0
18:13:51.298343 ens4  Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [R], seq 1606152476, win 0, length 0


กลับไปที่หน้าต่างแท็บ 2 แล้วตรวจสอบข้อมูล tcpdump คุณจะเห็นว่าคุณเข้าถึงปลายทางระดับภูมิภาคของ Cloud KMS ผ่านปลายทาง PSC ที่สร้างขึ้นได้ และปลายทางระดับภูมิภาค europe-west9 จะได้รับการแก้ไขแบบส่วนตัวไปยังโซน Managed Cloud DNS ที่คุณสร้างขึ้น บรรทัดที่เกี่ยวข้องในเอาต์พุต tcpdump จะไฮไลต์ไว้ด้านบนและอ้างอิงไว้ด้านล่าง

18:13:51.229638 ens4 In IP 169.254.169.254.53 > 10.0.0.2.52121: 8885 1/0/1 A 10.0.0.100 (78) (เซิร์ฟเวอร์ข้อมูลเมตาของ GCP ตอบกลับด้วยระเบียน A: 10.0.0.100 ซึ่งเป็น IP ของตัวจัดสรรภาระงาน การแก้ไข DNS ทำงานได้อย่างถูกต้อง europe-west9-cloudkms.example.com จะแก้ไขเป็น 10.0.0.100 ซึ่งเป็น IP ของตัวจัดสรรภาระงาน)

18:13:51.230390 ens4 Out IP 10.0.0.2.59474 > 10.0.0.100.443: Flags [S], seq 1606150798, win 65320, options [mss 1420,sackOK,TS val 4135800856 ecr 0,nop,wscale 7], length 0 (แสดงการแฮนด์เชค TCP สำหรับการเชื่อมต่อ HTTPS กับ IP ของตัวจัดสรรภาระงาน)

ในแท็บ 3, client-vm

dig europe-west9-cloudkms.example.com

ผลลัพธ์ที่คาดหวัง

; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> europe-west9-cloudkms.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7008
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;europe-west9-cloudkms.example.com. IN  A

;; ANSWER SECTION:
europe-west9-cloudkms.example.com. 300 IN A     10.0.0.100

;; Query time: 12 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Fri Oct 11 20:03:00 UTC 2024
;; MSG SIZE  rcvd: 78

เอาต์พุตของคำสั่ง dig แสดงให้เห็นว่า URL ที่กำหนดเองซึ่งเราสร้างขึ้นสำหรับ europe-west9-cloudkms.example.com จะเปลี่ยนเส้นทางไปยัง 10.0.0.100 ได้อย่างถูกต้อง ซึ่งเป็น IP ของตัวจัดสรรภาระงานภายใน คำขอไปยัง europe-west9-cloudkms.example.com จะได้รับการนำไปยังตัวจัดสรรภาระงานภายใน ซึ่งจะส่งต่อคำขอไปยังปลายทางระดับภูมิภาคของ KMS ผ่าน Private Service Connect

ตอนนี้คุณปิดแท็บ SSH ทั้ง 2 แท็บไปยัง client-vm ได้แล้ว

12. ขั้นตอนการล้างข้อมูล

ลบคอมโพเนนต์ของ Lab จากเทอร์มินัล Cloud Shell เดียว

# Set environment variables

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
export REGION=europe-west9
export ZONE=europe-west9-a
export VPC_NAME="consumer-vpc"
export SUBNET_NAME="consumer-subnet-1"
export NEG_NAME="l7psc-kms-neg"
export BACKEND_SERVICE_NAME="l7-psc-kms"
export CERT_NAME="my-ssl-cert"
export PROXY_NAME="psc-http-proxy"
export LB_RULE_NAME="kms-lb-rule"
export DNS_ZONE_NAME="example-com-private-zone"

#  Delete DNS records and zone

gcloud dns record-sets delete europe-west9-cloudkms.example.com. \
    --zone=${DNS_ZONE_NAME} --type=A --quiet
gcloud dns managed-zones delete ${DNS_ZONE_NAME} --quiet

#  Delete Load Balancer components

gcloud compute forwarding-rules delete ${LB_RULE_NAME} --region=${REGION} --quiet
gcloud compute target-https-proxies delete ${PROXY_NAME} --region=${REGION} --quiet
gcloud compute url-maps delete l7-psc-url-map --region=${REGION} --quiet
gcloud compute backend-services delete ${BACKEND_SERVICE_NAME} --region=${REGION} --quiet
gcloud compute network-endpoint-groups delete ${NEG_NAME} --region=${REGION} --quiet

# Delete SSL certificate

gcloud compute ssl-certificates delete ${CERT_NAME} --region=${REGION} --quiet

#  Delete VM instance

gcloud compute instances delete client-vm --zone=${ZONE} --quiet

#  Delete firewall rules

gcloud compute firewall-rules delete allow-ssh-iap --quiet

# Delete Cloud NAT and router

gcloud compute routers nats delete europe-nat --router=crnat --region=${REGION} --quiet
gcloud compute routers delete crnat --region=${REGION} --quiet

#  Delete subnets and VPC

gcloud compute networks subnets delete ${SUBNET_NAME} --region=${REGION} --quiet
gcloud compute networks subnets delete eu-west9-proxy-subnet --region=${REGION} --quiet
gcloud compute networks delete ${VPC_NAME} --quiet

# Schedule KMS key for deletion and provide instructions for keyring deletion

gcloud kms keys remove-iam-policy-binding europe-key \
    --location ${REGION} \
    --keyring europe-kr \
    --member serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com \
    --role roles/cloudkms.admin

gcloud kms keys versions destroy 1 --location=${REGION} --keyring=europe-kr --key=europe-key

#  Disable services (optional, only if you want to completely disable these APIs)

gcloud services disable compute.googleapis.com --force
gcloud services disable servicedirectory.googleapis.com --force
gcloud services disable dns.googleapis.com --force
gcloud services disable cloudkms.googleapis.com --force

#  Clean up local files

rm -f private.key server.csr server.crt csr_config.cnf startup.sh

13. ยินดีด้วย

ขอแสดงความยินดีที่ทำ Codelab เสร็จสมบูรณ์