1. บทนำ
ภาพรวม
องค์กรจำนวนมากใช้เครือข่าย Virtual Private Cloud (VCP) บน Google Cloud ที่มีการควบคุมขอบเขตเพื่อป้องกันการขโมยข้อมูลเพื่อรักษาความปลอดภัยการจราจรของข้อมูลในเครือข่ายสำหรับบริการและแอปพลิเคชัน เครือข่าย VPC คือเครือข่ายจริงเวอร์ชันเสมือนที่ใช้งานภายในเครือข่ายที่ใช้งานจริงของ Google เครือข่าย VPC มอบการเชื่อมต่อสำหรับอินสแตนซ์เครื่องเสมือน (VM) ของ Compute Engine, มอบตัวจัดสรรภาระงานของเครือข่ายแบบส่งผ่านภายในและระบบพร็อกซีสำหรับตัวจัดสรรภาระงานแอปพลิเคชันภายใน เชื่อมต่อกับเครือข่ายภายในองค์กรโดยใช้อุโมงค์ข้อมูล VPN ของ Cloud และไฟล์แนบ VLAN สำหรับ Cloud Interconnect รวมถึงกระจายการรับส่งข้อมูลจากตัวจัดสรรภาระงานภายนอกของ Google Cloud ไปยังแบ็กเอนด์
ซึ่งแตกต่างจาก VM ตรงที่บริการ Cloud Run จะไม่เชื่อมโยงกับเครือข่าย VPC ใดๆ โดยค่าเริ่มต้น Codelab นี้แสดงวิธีเปลี่ยนการตั้งค่าขาเข้า (การเชื่อมต่อขาเข้า) โดยจะมีเพียงการรับส่งข้อมูลที่มาจาก VPC เท่านั้นที่เข้าถึงบริการ Cloud Run ได้ (เช่น บริการแบ็กเอนด์) นอกจากนี้ Codelab นี้จะแสดงวิธีเข้าถึงบริการที่ 2 (เช่น บริการฟรอนท์เอนด์) เข้าถึงทั้งบริการ Cloud Run แบ็กเอนด์ผ่าน VPC และเพื่อให้มีสิทธิ์เข้าถึงอินเทอร์เน็ตสาธารณะต่อไป
ในตัวอย่างนี้ บริการ Cloud Run แบ็กเอนด์จะแสดง Hello World บริการ Cloud Run ฟรอนท์เอนด์มีช่องป้อนข้อมูลใน UI เพื่อรวบรวม URL จากนั้นบริการฟรอนท์เอนด์จะส่งคำขอ GET ไปยัง URL นั้น (เช่น บริการแบ็กเอนด์) จึงทําให้บริการนี้เป็นคำขอบริการ (แทนคำขอเบราว์เซอร์ไปยังบริการ) เมื่อบริการฟรอนท์เอนด์สามารถเข้าถึงแบ็กเอนด์ได้สำเร็จ ข้อความ Hello World จะปรากฏในเบราว์เซอร์ จากนั้น คุณจะโทรหา https://curlmyip.org เพื่อเรียกข้อมูลที่อยู่ IP ของบริการฟรอนท์เอนด์ได้
สิ่งที่คุณจะได้เรียนรู้
- วิธีอนุญาตเฉพาะการรับส่งข้อมูลจาก VPC ไปยังบริการ Cloud Run ของคุณ
- วิธีกำหนดค่าข้อมูลขาออกในบริการ Cloud Run (เช่น ฟรอนท์เอนด์) เพื่อสื่อสารกับบริการ Cloud Run ขาเข้าภายในเท่านั้น (เช่น แบ็กเอนด์) ขณะที่ยังคงรักษาการเข้าถึงอินเทอร์เน็ตสาธารณะสำหรับบริการฟรอนท์เอนด์
2. การตั้งค่าและข้อกำหนด
ข้อกำหนดเบื้องต้น
- คุณเข้าสู่ระบบ Cloud Console แล้ว
- คุณได้ทำให้ฟังก์ชันรุ่นที่ 2 ใช้งานได้ก่อนหน้านี้ เช่น คุณสามารถทำตามการเริ่มต้นใช้งาน Cloud Function รุ่นที่ 2 อย่างรวดเร็วเพื่อเริ่มต้นใช้งาน
เปิดใช้งาน Cloud Shell
- คลิกเปิดใช้งาน Cloud Shell
จาก Cloud Console
หากเริ่มต้นใช้งาน Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอตรงกลางที่อธิบายว่านี่คืออะไร หากระบบแสดงหน้าจอตรงกลาง ให้คลิกต่อไป
การจัดสรรและเชื่อมต่อกับ Cloud Shell ใช้เวลาเพียงไม่กี่นาที
เครื่องเสมือนนี้โหลดด้วยเครื่องมือการพัฒนาทั้งหมดที่จำเป็น โดยมีไดเรกทอรีหลักขนาด 5 GB ถาวรและทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานส่วนใหญ่ใน Codelab นี้สามารถทำได้โดยใช้เบราว์เซอร์
เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นข้อความตรวจสอบสิทธิ์และโปรเจ็กต์ได้รับการตั้งค่าเป็นรหัสโปรเจ็กต์แล้ว
- เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list
เอาต์พุตจากคำสั่ง
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้เกี่ยวกับโปรเจ็กต์ของคุณ
gcloud config list project
เอาต์พุตจากคำสั่ง
[core] project = <PROJECT_ID>
หากไม่ใช่ ให้ตั้งคำสั่งด้วยคำสั่งนี้
gcloud config set project <PROJECT_ID>
เอาต์พุตจากคำสั่ง
Updated property [core/project].
3. สร้างบริการ Cloud Run
ตั้งค่าตัวแปรสภาพแวดล้อม
คุณกำหนดตัวแปรสภาพแวดล้อมที่จะใช้ตลอดทั้ง Codelab ได้
PROJECT_ID=<YOUR_PROJECT_ID> REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend-with-internet BACKEND=backend SUBNET_NAME=default
สร้างบริการ Cloud Run แบ็กเอนด์
ขั้นแรก ให้สร้างไดเรกทอรีสำหรับซอร์สโค้ดและ cd ลงในไดเรกทอรีนั้น
mkdir -p egress-private-codelab/frontend-w-internet egress-private-codelab/backend && cd egress-private-codelab/backend
จากนั้นสร้างไฟล์ `package.json`` ด้วยเนื้อหาต่อไปนี้
{ "name": "backend-service", "version": "1.0.0", "description": "", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.18.1" } }
จากนั้นสร้างไฟล์ต้นฉบับ index.js
ที่มีเนื้อหาด้านล่าง ไฟล์นี้ประกอบด้วยจุดแรกเข้าสำหรับบริการและประกอบด้วยตรรกะหลักสำหรับแอป
const express = require('express'); const app = express(); app.use(express.urlencoded({ extended: true })); app.get('/', function (req, res) { res.send("hello world"); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`helloworld: listening on port ${port}`); });
สุดท้าย ทำให้บริการ Cloud Run ใช้งานได้โดยเรียกใช้คำสั่งต่อไปนี้
gcloud run deploy $BACKEND --source . --allow-unauthenticated --region $REGION
สร้างบริการ Cloud Run ฟรอนท์เอนด์
ไปที่ไดเรกทอรีฟรอนท์เอนด์
cd ../frontend-w-internet
จากนั้นสร้างไฟล์ package.json
ที่มีเนื้อหาต่อไปนี้
{ "name": "frontend", "version": "1.0.0", "description": "", "scripts": { "start": "node index.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "axios": "^1.6.6", "express": "^4.18.2", "htmx.org": "^1.9.10" } }
จากนั้นสร้างไฟล์ต้นฉบับ index.js
ที่มีเนื้อหาด้านล่าง ไฟล์นี้ประกอบด้วยจุดแรกเข้าสำหรับบริการและประกอบด้วยตรรกะหลักสำหรับแอป
const express = require("express"); const app = express(); const port = 8080; const path = require('path'); const axios = require('axios'); // serve static content (index.html) using // built-in middleware function in Express app.use(express.static('public')); app.use(express.urlencoded({ extended: true })); // this endpoint receives a URL in the post body // and then makes a get request to that URL // results are sent back to the caller app.post('/callService', async (req, res) => { const url = req.body.url; let message = ""; try { console.log("url: ", url); const response = await axios.get(url); message = response.data; } catch (error) { message = error.message; console.error(error.message); } res.send(` ${message} <p> </p> `); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
สร้างไดเรกทอรีสาธารณะสำหรับไฟล์index.html
mkdir public touch public/index.html
และอัปเดต index.html
ให้มีข้อมูลต่อไปนี้
<html> <script src="https://unpkg.com/htmx.org@1.9.10" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous" ></script> <body> <div style="margin-top: 100px; margin-left: 100px"> <h1>I'm the Request Tester service on the Internet</h1> <form hx-trigger="submit" hx-post="/callService" hx-target="#zen"> <label for="url"> URL:</label> <input style="width: 308px" type="text" id="url" name="url" placeholder="The backend service URL" required /> <button hx-indicator="#loading" type="submit">Submit</button> <p></p> <span class="htmx-indicator" id="loading"> Loading... </span> <div id="zen" style="white-space: pre-wrap"></div> <p></p> </form> </div> </body> </html>
สุดท้าย ทำให้บริการ Cloud Run ใช้งานได้โดยเรียกใช้คำสั่งต่อไปนี้
gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION
โทรหาบริการแบ็กเอนด์
ในส่วนนี้ คุณจะต้องยืนยันว่าคุณได้ทำให้บริการ Cloud Run ใช้งานได้ 2 บริการเรียบร้อยแล้ว
เปิด URL ของบริการฟรอนท์เอนด์ในเว็บเบราว์เซอร์ เช่น https://frontend-your-hash-uc.a.run.app/
ในกล่องข้อความ ให้ป้อน URL สำหรับบริการแบ็กเอนด์ โปรดทราบว่าระบบกำหนดเส้นทางคำขอนี้จากอินสแตนซ์ Cloud Run ฟรอนท์เอนด์ไปยังบริการ Cloud Run แบ็กเอนด์ ไม่ใช่จากเบราว์เซอร์ของคุณ
คุณจะเห็นคำว่า "สวัสดีโลก"
4. ตั้งค่าบริการแบ็กเอนด์สำหรับการรับส่งข้อมูลขาเข้าภายในเท่านั้น
คุณเรียกใช้คำสั่ง gcloud ต่อไปนี้เพื่อรวมบริการ Cloud Run เข้ากับเครือข่ายส่วนตัวได้
gcloud run services update $BACKEND --ingress internal --region $REGION
หากคุณลองเรียกใช้บริการแบ็กเอนด์จากบริการฟรอนท์เอนด์ คุณจะได้รับข้อผิดพลาด 404 การเชื่อมต่อขาออกของบริการ Cloud Run ฟรอนท์เอนด์ (หรือขาออก) จะออกไปยังอินเทอร์เน็ตก่อน ดังนั้น Google Cloud จึงจะไม่ทราบต้นทางของคำขอ
5. กำหนดค่าบริการฟรอนท์เอนด์เพื่อเข้าถึง VPC
ในส่วนนี้ คุณจะได้กำหนดค่าบริการ Cloud Run ฟรอนท์เอนด์เพื่อสื่อสารกับบริการแบ็กเอนด์ผ่าน VPC
ในการดำเนินการนี้ คุณจะต้องเพิ่มข้อมูลขาออก VPC โดยตรงไปยังบริการ Cloud Run ฟรอนท์เอนด์เพื่อให้แน่ใจว่าจะเข้าถึงที่อยู่ IP ภายในบนเครือข่าย VPC ได้ จากนั้นจึงกำหนดค่าข้อมูลขาออกให้กำหนดเส้นทางเฉพาะคำขอไปยัง IP ส่วนตัวไปยัง VPC การกำหนดค่านี้จะทำให้ฟรอนท์เอนด์ยังคงเข้าถึงอินเทอร์เน็ตสาธารณะได้ ดูข้อมูลเพิ่มเติมในเอกสารประกอบเกี่ยวกับการได้รับคำขอจากบริการ Cloud Run อื่นๆ
กำหนดค่าข้อมูลขาออก VPC โดยตรง
ก่อนอื่น ให้เรียกใช้คำสั่งนี้เพื่อใช้ข้อมูลขาออก VPC โดยตรงในบริการฟรอนท์เอนด์
gcloud beta run services update $FRONTEND \ --network=$SUBNET_NAME \ --subnet=$SUBNET_NAME \ --vpc-egress=private-ranges-only \ --region=$REGION
ตอนนี้คุณจะยืนยันว่าบริการฟรอนท์เอนด์มีสิทธิ์เข้าถึง VPC ได้แล้ว โดยทำดังนี้
gcloud beta run services describe $FRONTEND \ --region=$REGION
คุณควรเห็นผลลัพธ์คล้ายกับ
VPC access: Network: default Subnet: default Egress: private-ranges-only
เปิดใช้การเข้าถึง Google แบบส่วนตัว
ถัดไป คุณจะเปิดใช้การเข้าถึง Google แบบส่วนตัวในซับเน็ตโดยการเรียกใช้คำสั่งต่อไปนี้
gcloud compute networks subnets update $SUBNET_NAME \ --region=$REGION \ --enable-private-ip-google-access
คุณสามารถตรวจสอบว่าได้เปิดใช้การเข้าถึง Google แบบส่วนตัวแล้วโดยเรียกใช้คำสั่งนี้
gcloud compute networks subnets describe $SUBNET_NAME \ --region=$REGION \ --format="get(privateIpGoogleAccess)"
สร้างโซน Cloud DNS สำหรับ URL run.app
สุดท้าย ให้สร้างโซน Cloud DNS สำหรับ URL run.app เพื่อให้ Google Cloud พิจารณาเป็นที่อยู่ IP ภายในได้
ในขั้นตอนก่อนหน้าเมื่อคุณกำหนดค่าข้อมูลขาออก VPC โดยตรงเป็นช่วงส่วนตัวเท่านั้น ซึ่งหมายความว่าการเชื่อมต่อขาออกจากบริการฟรอนท์เอนด์จะส่งไปยังเครือข่าย VPC ต่อเมื่อปลายทางเป็น IP ภายในเท่านั้น แต่บริการแบ็กเอนด์จะใช้ URL Run.app ที่แก้ไขเป็น IP สาธารณะ
ในขั้นตอนนี้ คุณจะสร้างโซน Cloud DNS สำหรับ URL run.app เพื่อแก้ไขช่วงที่อยู่ IP ของ private.googleapis.com ซึ่งยอมรับเป็นที่อยู่ IP ภายใน ตอนนี้ คำขอที่ส่งไปยังช่วงเหล่านี้จะได้รับการกำหนดเส้นทางผ่านเครือข่าย VPC ของคุณ
โดยไปที่ https://cloud.google.com/run/docs/securing/private-networking#from-other-services
# do not include the https:// in your DNS Name # for example: backend-<hash>-uc.a.run.app DNS_NAME=<your backend service URL without the https://> gcloud dns --project=$PROJECT_ID managed-zones create codelab-backend-service \ --description="" \ --dns-name="a.run.app." \ --visibility="private" \ --networks=$SUBNET_NAME gcloud dns --project=$PROJECT_ID record-sets create $DNS_NAME. \ --zone="codelab-backend-service" \ --type="A" \ --ttl="60" \ --rrdatas="199.36.153.8,199.36.153.9,199.36.153.10,199.36.153.11"
ต่อไปนี้เมื่อคุณพยายามเข้าถึงบริการแบ็กเอนด์สำหรับเว็บไซต์ของคุณ คุณจะเห็น "สวัสดีโลก" ส่งคืนแล้ว
และเมื่อคุณพยายามเข้าถึงอินเทอร์เน็ตโดยใช้ https://curlmyip.org/ คุณจะเห็นที่อยู่ IP ของคุณ
6. การแก้ปัญหา
ต่อไปนี้คือข้อความแสดงข้อผิดพลาดบางส่วนที่คุณอาจพบหากไม่ได้กำหนดการตั้งค่าอย่างถูกต้อง
- หากได้รับข้อผิดพลาด
getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.app
โปรดตรวจสอบว่าไม่ได้เพิ่ม "https://" ลงในระเบียน DNS A - หากคุณได้รับข้อผิดพลาด 404 เมื่อพยายามเข้าถึงแบ็กเอนด์หลังจากกำหนดค่าโซน คุณสามารถรอให้แคชในระเบียน run.app ส่วนกลางหมดอายุ (เช่น 6 ชั่วโมง) หรือจะสร้างการแก้ไขใหม่ (เพื่อให้ล้างแคช) โดยเรียกใช้คำสั่งต่อไปนี้:
gcloud beta run services update $FRONTEND --network=$SUBNET_NAME --subnet=$SUBNET_NAME --vpc-egress=private-ranges-only --region=$REGION
7. ยินดีด้วย
ขอแสดงความยินดีที่เรียน Codelab จนจบ
เราขอแนะนำให้อ่านเอกสารเกี่ยวกับ Private Networking on Cloud Run
หัวข้อที่ครอบคลุม
- วิธีอนุญาตเฉพาะการรับส่งข้อมูลจาก VPC ไปยังบริการ Cloud Run ของคุณ
- วิธีกำหนดค่าข้อมูลขาออกในบริการ Cloud Run (เช่น ฟรอนท์เอนด์) เพื่อสื่อสารกับบริการ Cloud Run ขาเข้าภายในเท่านั้น (เช่น แบ็กเอนด์) ขณะที่ยังคงรักษาการเข้าถึงอินเทอร์เน็ตสาธารณะสำหรับบริการฟรอนท์เอนด์
8. ล้างข้อมูล
เพื่อหลีกเลี่ยงการเรียกเก็บเงินที่ไม่ตั้งใจ (เช่น หากมีการเรียกใช้บริการ Cloud Run นี้โดยไม่ได้ตั้งใจมากกว่าการจัดสรรการเรียกใช้ Cloud Run รายเดือนในระดับฟรี) คุณจะลบบริการ Cloud Run หรือลบโปรเจ็กต์ที่คุณสร้างในขั้นตอนที่ 2 ก็ได้
หากต้องการลบบริการ Cloud Run ให้ไปที่ Cloud Console ของ Cloud Run ที่ https://console.cloud.google.com/functions/ และลบบริการ $FRONTEND และ $BACKEND ที่คุณสร้างไว้ใน Codelab นี้
หากเลือกลบทั้งโปรเจ็กต์ ให้ไปที่ https://console.cloud.google.com/cloud-resource-manager เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนที่ 2 แล้วเลือกลบ หากลบโปรเจ็กต์ คุณจะต้องเปลี่ยนโปรเจ็กต์ใน Cloud SDK คุณสามารถดูรายการโปรเจ็กต์ที่ใช้ได้ทั้งหมดโดยเรียกใช้ gcloud projects list