1. مقدمة
نظرة عامة
لتأمين حركة بيانات الشبكة لخدماتها وتطبيقاتها، تستخدم العديد من المؤسسات شبكة "سحابة إلكترونية خاصة افتراضية" (VCP) على Google Cloud مع عناصر تحكّم في المحيط لمنع استخراج البيانات. شبكة السحابة الافتراضية الخاصة هي نسخة افتراضية من شبكة فعلية يتم تنفيذها داخل شبكة الإنتاج في Google. توفّر شبكة VPC إمكانية الاتصال لأجهزة Compute Engine الافتراضية، وتوفّر موازنات الحمل الأصلية الداخلية على الشبكة التي تعمل بنقل البيانات المباشر وأنظمة الخادم الوكيل لموازنات الحمل الداخلية للتطبيقات، وتتصل بالشبكات المحلية باستخدام أنفاق Cloud VPN ومرفقات شبكة VLAN لخدمة Cloud Interconnect، وتوزّع الزيارات من موازنات الحمل الخارجية في Google Cloud على الخلفيات.
على عكس الأجهزة الافتراضية، لا ترتبط خدمات Cloud Run بأي شبكة VPC معيّنة تلقائيًا. يوضّح هذا الدرس التطبيقي حول الترميز كيفية تغيير إعدادات حركة البيانات الواردة (الاتصالات الواردة) بحيث لا يمكن إلا للزيارات الواردة من شبكة VPC الوصول إلى خدمة Cloud Run (مثل خدمة الخلفية). بالإضافة إلى ذلك، يوضّح لك هذا الدرس التطبيقي حول الترميز كيفية إتاحة وصول خدمة ثانية (مثل خدمة الواجهة الأمامية) إلى خدمة Cloud Run للخادم الخلفي من خلال شبكة VPC، بالإضافة إلى مواصلة إتاحة الوصول إلى الإنترنت المتاح للجميع.
في هذا المثال، تعرض خدمة Cloud Run الخلفية عبارة "hello world". توفّر خدمة Cloud Run للواجهة الأمامية حقل إدخال في واجهة المستخدم لجمع عنوان URL. بعد ذلك، ترسل خدمة الواجهة الأمامية طلب استرداد بيانات باستخدام GET إلى عنوان URL هذا (مثل خدمة الخلفية)، ما يجعل هذا طلب خدمة إلى خدمة (بدلاً من طلب من المتصفح إلى الخدمة). عندما تتمكّن خدمة الواجهة الأمامية من الوصول إلى الواجهة الخلفية بنجاح، ستظهر الرسالة hello world في المتصفّح. بعد ذلك، ستتعرّف على كيفية إجراء مكالمة إلى https://curlmyip.org لاسترداد عنوان IP لخدمة الواجهة الأمامية.
ما ستتعلمه
- كيفية السماح فقط بحركة البيانات من شبكة VPC إلى خدمة Cloud Run
- كيفية ضبط الخروج في خدمة Cloud Run (مثل الواجهة الأمامية) للتواصل مع خدمة Cloud Run التي تتضمّن دخولاً داخليًا فقط (مثل الخلفية)، مع الحفاظ على إمكانية وصول خدمة الواجهة الأمامية إلى الإنترنت المتاح للجميع
2. الإعداد والمتطلبات
المتطلبات الأساسية
- يجب أن تكون مسجّلاً الدخول إلى Cloud Console.
- سبق لك نشر دالة من الجيل الثاني. على سبيل المثال، يمكنك اتّباع دليل البدء السريع في الجيل الثاني من Cloud Functions للبدء.
تفعيل Cloud Shell
- من Cloud Console، انقر على تفعيل Cloud Shell
.

إذا كانت هذه هي المرة الأولى التي تبدأ فيها Cloud Shell، ستظهر لك شاشة وسيطة توضّح ماهيتها. إذا ظهرت لك شاشة وسيطة، انقر على متابعة.

يستغرق توفير Cloud Shell والاتصال به بضع لحظات فقط.

يتم تحميل هذا الجهاز الافتراضي بجميع أدوات التطوير اللازمة. توفّر هذه الخدمة دليلًا رئيسيًا دائمًا بسعة 5 غيغابايت وتعمل في Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. يمكن إنجاز معظم عملك في هذا الدرس العملي، إن لم يكن كله، باستخدام متصفح.
بعد الاتصال بـ 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
إعداد متغيرات البيئة
يمكنك ضبط متغيّرات البيئة التي سيتم استخدامها في جميع مراحل هذا الدرس البرمجي.
PROJECT_ID=<YOUR_PROJECT_ID> REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend-with-internet BACKEND=backend SUBNET_NAME=default
إنشاء خدمة Cloud Run للخلفية
أولاً، أنشئ دليلاً لرمز المصدر وانتقِل إلى هذا الدليل.
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 بنجاح.
افتح عنوان URL الخاص بخدمة الواجهة الأمامية في متصفّح الويب، مثل https://frontend-your-hash-uc.a.run.app/
في مربّع النص، أدخِل عنوان URL لخدمة الخلفية. يُرجى العِلم أنّه يتم توجيه هذا الطلب من مثيل Cloud Run للواجهة الأمامية إلى خدمة Cloud Run للخلفية، وليس من متصفّحك.
سيظهر لك "hello world"
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
يمكنك التأكّد من تفعيل ميزة Private Google Access من خلال تنفيذ الأمر التالي:
gcloud compute networks subnets describe $SUBNET_NAME \ --region=$REGION \ --format="get(privateIpGoogleAccess)"
إنشاء منطقة نظام أسماء النطاقات (DNS) لـ 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"
الآن، عندما تحاول الوصول إلى خدمة الخلفية لموقعك الإلكتروني، سيظهر لك الردّ "hello world".
وعند محاولة الوصول إلى الإنترنت باستخدام https://curlmyip.org/، سيظهر لك عنوان IP الخاص بك.
6. تحديد المشاكل وحلّها
في ما يلي بعض رسائل الخطأ المحتملة التي قد تظهر لك إذا لم يتم ضبط الإعدادات بشكل صحيح.
- إذا ظهرت لك رسالة خطأ
getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.appتأكَّد من أنّك لم تُضِف "https://" إلى سجلّ 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. تهانينا!
تهانينا على إكمال هذا الدرس العملي.
ننصحك بمراجعة المستندات حول الشبكات الخاصة على Cloud Run.
المواضيع التي تناولناها
- كيفية السماح فقط بالزيارات من شبكة VPC إلى خدمة Cloud Run
- كيفية ضبط الخروج في خدمة Cloud Run (مثل الواجهة الأمامية) للتواصل مع خدمة Cloud Run التي تتضمّن دخولاً داخليًا فقط (مثل الخلفية)، مع الحفاظ على إمكانية وصول خدمة الواجهة الأمامية إلى الإنترنت المتاح للجميع
8. تَنظيم
لتجنُّب الرسوم غير المقصودة (على سبيل المثال، إذا تم استدعاء خدمة Cloud Run هذه مرات أكثر من عدد مرات استدعاء Cloud Run المخصّصة لك شهريًا في الطبقة المجانية)، يمكنك إما حذف خدمة Cloud Run أو حذف المشروع الذي أنشأته في الخطوة 2.
لحذف خدمات Cloud Run، انتقِل إلى Cloud Run Cloud Console على https://console.cloud.google.com/functions/ واحذف الخدمات $FRONTEND و $BACKEND التي أنشأتها في هذا الدرس التطبيقي حول الترميز.
إذا اخترت حذف المشروع بأكمله، يمكنك الانتقال إلى https://console.cloud.google.com/cloud-resource-manager، واختيار المشروع الذي أنشأته في الخطوة 2، ثم النقر على "حذف". إذا حذفت المشروع، عليك تغيير المشاريع في Cloud SDK. يمكنك الاطّلاع على قائمة بجميع المشاريع المتاحة من خلال تنفيذ gcloud projects list.