۱. مقدمه
نمای کلی
برای ایمنسازی ترافیک شبکه برای سرویسها و برنامههای کاربردی خود، بسیاری از سازمانها از یک شبکه ابر خصوصی مجازی (VCP) در Google Cloud با کنترلهای محیطی برای جلوگیری از خروج دادهها استفاده میکنند. یک شبکه VPC یک نسخه مجازی از یک شبکه فیزیکی است که در داخل شبکه تولید گوگل پیادهسازی شده است. یک شبکه VPC اتصال را برای نمونههای ماشین مجازی (VM) Compute Engine شما فراهم میکند، متعادلکنندههای بار شبکه داخلی بومی و سیستمهای پروکسی را برای متعادلکنندههای بار برنامه داخلی ارائه میدهد، با استفاده از تونلهای Cloud VPN و پیوستهای VLAN برای Cloud Interconnect به شبکههای داخلی متصل میشود و ترافیک را از متعادلکنندههای بار خارجی Google Cloud به backendها توزیع میکند.
برخلاف ماشینهای مجازی، سرویسهای Cloud Run به طور پیشفرض با هیچ شبکه VPC خاصی مرتبط نیستند. این آزمایشگاه کد نشان میدهد که چگونه تنظیمات ورودی (اتصالات ورودی) را تغییر دهید تا فقط ترافیکی که از یک VPC میآید بتواند به یک سرویس Cloud Run (مثلاً یک سرویس backend) دسترسی داشته باشد. علاوه بر این، این آزمایشگاه کد به شما نشان میدهد که چگونه یک سرویس دوم (مثلاً یک سرویس frontend) داشته باشید که هم به سرویس Cloud Run backend از طریق VPC دسترسی داشته باشد و هم به اینترنت عمومی دسترسی داشته باشد.
در این مثال، سرویس Cloud Run در سمت سرور backend عبارت hello world را برمیگرداند. سرویس Cloud Run در سمت سرور frontend یک فیلد ورودی در رابط کاربری برای جمعآوری یک URL فراهم میکند. سپس سرویس frontend یک درخواست GET به آن URL (مثلاً سرویس backend) ارسال میکند، از این رو این درخواست به یک درخواست سرویس به سرویس تبدیل میشود (به جای درخواست مرورگر به سرویس). هنگامی که سرویس frontend بتواند با موفقیت به backend برسد، پیام hello world در مرورگر نمایش داده میشود. سپس، خواهید دید که چگونه میتوانید برای بازیابی آدرس IP سرویس frontend خود، به https://curlmyip.org فراخوانی کنید.
آنچه یاد خواهید گرفت
- چگونه فقط ترافیک را از یک VPC به سرویس Cloud Run خود مجاز کنیم؟
- نحوه پیکربندی خروجی در یک سرویس Cloud Run (مثلاً frontend) برای برقراری ارتباط با یک سرویس Cloud Run که فقط از ورودی داخلی استفاده میکند (مثلاً backend)، در حالی که دسترسی عمومی به اینترنت را برای سرویس frontend حفظ میکند.
۲. تنظیمات و الزامات
پیشنیازها
- شما وارد کنسول ابری شدهاید.
- شما قبلاً یک تابع نسل دوم را مستقر کردهاید. برای مثال، میتوانید برای شروع ، راهنمای استقرار یک تابع ابری نسل دوم را دنبال کنید.
فعال کردن پوسته ابری
- از کنسول ابری، روی فعال کردن پوسته ابری کلیک کنید
.

اگر این اولین باری است که Cloud Shell را اجرا میکنید، یک صفحه میانی برای توضیح آن به شما نمایش داده میشود. اگر با یک صفحه میانی مواجه شدید، روی ادامه کلیک کنید.

آمادهسازی و اتصال به Cloud Shell فقط چند لحظه طول میکشد.

این ماشین مجازی مجهز به تمام ابزارهای توسعه مورد نیاز است. این ماشین یک دایرکتوری خانگی پایدار ۵ گیگابایتی ارائه میدهد و در فضای ابری گوگل اجرا میشود که عملکرد شبکه و احراز هویت را تا حد زیادی افزایش میدهد. بخش عمدهای از کار شما در این آزمایشگاه کد، اگر نگوییم همه، را میتوان با یک مرورگر انجام داد.
پس از اتصال به 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].
۳. سرویسهای Cloud Run را ایجاد کنید
متغیرهای محیطی را تنظیم کنید
شما میتوانید متغیرهای محیطی که در سراسر این آزمایشگاه کد استفاده خواهند شد را تنظیم کنید.
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 را به صورت frontend ایجاد کنید
به دایرکتوری frontend بروید
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
با سرویس Backend تماس بگیرید
در این بخش، تأیید خواهید کرد که دو سرویس Cloud Run را با موفقیت مستقر کردهاید.
آدرس اینترنتی سرویس frontend را در مرورگر وب خود باز کنید، مثلاً https://frontend-your-hash-uc.a.run.app/
در کادر متن، آدرس اینترنتی (URL) سرویس بکاند را وارد کنید. توجه داشته باشید که این درخواست از نمونهی کلود ران (Cloud Run) در فرانتاند به سرویس کلود ران در بکاند هدایت میشود و نه از مرورگر شما.
شما عبارت "سلام دنیا" را خواهید دید.
۴. سرویس Backend را فقط برای ورودی داخلی تنظیم کنید
شما میتوانید دستور gcloud زیر را برای ادغام سرویس Cloud Run در شبکه خصوصی خود اجرا کنید.
gcloud run services update $BACKEND --ingress internal --region $REGION
اگر بخواهید سرویس بکاند را از سرویس فرانتاند فراخوانی کنید، با خطای ۴۰۴ مواجه خواهید شد. اتصال خروجی (یا خروجی) سرویس کلود ران فرانتاند ابتدا به اینترنت متصل میشود، بنابراین گوگل کلود مبدا درخواست را نمیداند.
۵. سرویس Frontend را برای دسترسی به VPC پیکربندی کنید
در این بخش، سرویس Cloud Run فرانتاند خود را برای ارتباط با سرویس بکاند از طریق یک VPC پیکربندی خواهید کرد.
برای انجام این کار، باید خروجی مستقیم VPC را به سرویس Cloud Run فرانتاند خود اضافه کنید تا مطمئن شوید که میتواند به آدرسهای IP داخلی در شبکه VPC دسترسی پیدا کند. سپس، خروجی را طوری پیکربندی میکنید که فقط درخواستهای مربوط به IPهای خصوصی به VPC هدایت شوند. این پیکربندی به فرانتاند شما اجازه میدهد تا همچنان به اینترنت عمومی دسترسی داشته باشد. میتوانید در مستندات مربوط به دریافت درخواستها از سایر سرویسهای Cloud Run اطلاعات بیشتری کسب کنید.
پیکربندی خروجی مستقیم VPC
ابتدا، این دستور را اجرا کنید تا از خروجی مستقیم VPC در سرویس frontend خود استفاده کنید:
gcloud beta run services update $FRONTEND \ --network=$SUBNET_NAME \ --subnet=$SUBNET_NAME \ --vpc-egress=private-ranges-only \ --region=$REGION
اکنون میتوانید تأیید کنید که سرویس frontend شما به VPC دسترسی دارد:
gcloud beta run services describe $FRONTEND \ --region=$REGION
شما باید خروجی مشابه زیر را ببینید
VPC access:
Network: default
Subnet: default
Egress: private-ranges-only
فعال کردن دسترسی خصوصی گوگل
در مرحله بعد، با اجرای دستور زیر، دسترسی خصوصی گوگل را در زیرشبکه فعال خواهید کرد:
gcloud compute networks subnets update $SUBNET_NAME \ --region=$REGION \ --enable-private-ip-google-access
با اجرای این دستور میتوانید تأیید کنید که دسترسی خصوصی به گوگل فعال شده است:
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 را روی private-ranges-only پیکربندی کردید، این بدان معناست که اتصالات خروجی از سرویس frontend شما فقط در صورتی به شبکه VPC میروند که مقصد یک IP داخلی باشد. با این حال، سرویس backend شما از یک 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"
حالا وقتی سعی میکنید به سرویس بکاند وبسایت خود دسترسی پیدا کنید، عبارت "hello world" را مشاهده خواهید کرد.
و وقتی سعی میکنید با استفاده از https://curlmyip.org/ به اینترنت دسترسی پیدا کنید، آدرس IP خود را مشاهده خواهید کرد.
۶. عیبیابی
در اینجا برخی از پیامهای خطای احتمالی که ممکن است در صورت پیکربندی نادرست تنظیمات با آنها مواجه شوید، آورده شده است.
- اگر با خطای
getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.appمواجه شدید، مطمئن شوید که "https://" را به رکورد DNS A اضافه نکردهاید. - اگر هنگام تلاش برای دسترسی به backend پس از پیکربندی zone با خطای ۴۰۴ مواجه شدید، میتوانید منتظر بمانید تا حافظه پنهان (cache) رکورد سراسری run.app منقضی شود (مثلاً ۶ ساعت) یا میتوانید با اجرای دستور زیر یک نسخه جدید ایجاد کنید (و در نتیجه حافظه پنهان را پاک کنید):
gcloud beta run services update $FRONTEND --network=$SUBNET_NAME --subnet=$SUBNET_NAME --vpc-egress=private-ranges-only --region=$REGION
۷. تبریک میگویم!
تبریک میگویم که آزمایشگاه کد را تمام کردید!
توصیه میکنیم مستندات مربوط به شبکه خصوصی در Cloud Run را بررسی کنید.
آنچه ما پوشش دادهایم
- چگونه فقط ترافیک را از یک VPC به سرویس Cloud Run خود مجاز کنیم؟
- نحوه پیکربندی خروجی در یک سرویس Cloud Run (مثلاً frontend) برای برقراری ارتباط با یک سرویس Cloud Run که فقط از ورودی داخلی استفاده میکند (مثلاً backend)، در حالی که دسترسی عمومی به اینترنت را برای سرویس frontend حفظ میکند.
۸. تمیز کردن
برای جلوگیری از هزینههای ناخواسته، (برای مثال، اگر این سرویس Cloud Run سهواً بیشتر از تخصیص فراخوانی ماهانه Cloud Run شما در سطح رایگان فراخوانی شود)، میتوانید سرویس Cloud Run یا پروژهای را که در مرحله 2 ایجاد کردهاید، حذف کنید.
برای حذف سرویسهای Cloud Run، به کنسول ابری Cloud Run در آدرس https://console.cloud.google.com/functions/ بروید و سرویسهای $FRONTEND و $BACKEND که در این آزمایشگاه کد ایجاد کردهاید را حذف کنید.
اگر تصمیم به حذف کل پروژه دارید، میتوانید به آدرس https://console.cloud.google.com/cloud-resource-manager بروید، پروژهای را که در مرحله ۲ ایجاد کردهاید انتخاب کنید و گزینه Delete را انتخاب کنید. اگر پروژه را حذف کنید، باید پروژهها را در Cloud SDK خود تغییر دهید. میتوانید با اجرای gcloud projects list لیست تمام پروژههای موجود را مشاهده کنید.