تهيئة خدمة تشغيل في السحابة الإلكترونية للوصول إلى كل من خدمة تشغيل السحابة الإلكترونية الداخلية وشبكة الإنترنت العامة

1. مقدمة

نظرة عامة

لتأمين حركة بيانات الشبكة لخدماتها وتطبيقاتها، تستخدم العديد من المؤسسات شبكة سحابة إلكترونية خاصة افتراضية (VCP) على Google Cloud مع عناصر تحكُّم في المحيط لمنع استخراج البيانات. شبكة VC هي نسخة افتراضية من شبكة مادية يتم تنفيذها داخل شبكة الإنتاج في Google. توفّر شبكة VPC إمكانية الاتصال لمثيلات الجهاز الافتراضي (VM) في Compute Engine، وتوفّر أجهزة موازنة حمل الشبكة الداخلية العبور الداخلية والأنظمة الوكيلة لأجهزة موازنة حمل التطبيقات الداخلية، وتتصل بالشبكات داخل الشركة باستخدام أنفاق Cloud VPN ومرفقات VLAN في Cloud Interconnect، وتوزِّع حركة البيانات من أجهزة موازنة الحمل الخارجية في Google Cloud إلى الخلفيات.

على عكس الأجهزة الافتراضية، لا ترتبط خدمات تشغيل السحابة الإلكترونية تلقائيًا بأي شبكة VPC معيّنة. يشرح هذا الدرس التطبيقي حول الترميز كيفية تغيير إعدادات الدخول (الاتصالات الواردة)، بحيث لا يمكن إلا للزيارات الواردة من شبكة VPC الوصول إلى خدمة تشغيل السحابة الإلكترونية (مثل خدمة الخلفية). بالإضافة إلى ذلك، يوضّح لك هذا الدرس التطبيقي حول الترميز كيفية الحصول على خدمة ثانية (مثل خدمة واجهة أمامية) للوصول إلى خدمة تشغيل السحابة الإلكترونية التي تعمل في الخلفية من خلال شبكة VPC ومواصلة الحصول على اتصال عام بالإنترنت.

في هذا المثال، تعرض خدمة Cloud Run التي تعمل في الخلفية كلمة hello world. توفر خدمة Cloud Run في الواجهة الأمامية حقل إدخال في واجهة المستخدم لجمع عنوان URL. ثم تقدم خدمة الواجهة الأمامية طلب GET إلى عنوان URL هذا (مثل خدمة الخلفية)، مما يجعل هذا الطلب خدمة لطلب خدمة (بدلاً من طلب من متصفح إلى خدمة). عندما تتمكن خدمة الواجهة الأمامية من الوصول إلى الواجهة الخلفية بنجاح، يتم عرض رسالة "مرحبًا" في المتصفِّح. بعد ذلك، سترى كيف يمكنك إجراء اتصال بـ https://curlmyip.org لاسترداد عنوان IP لخدمة الواجهة الأمامية.

المعلومات التي ستطّلع عليها

  • كيفية السماح بالزيارات من شبكة VPC فقط إلى خدمة تشغيل السحابة الإلكترونية
  • كيفية إعداد الخروج في خدمة Cloud Run (مثل الواجهة الأمامية) للاتصال بخدمة Cloud Run التي تتيح الدخول الداخلي فقط (مثل الخلفية) مع الحفاظ على إمكانية الوصول العام إلى الإنترنت لخدمة الواجهة الأمامية

2. الإعداد والمتطلبات

المتطلبات الأساسية

تفعيل Cloud Shell

  1. من Cloud Console، انقر على تفعيل Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

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

d95252b003979716.png

من المفترَض أن تستغرق عملية إدارة الحسابات والاتصال بخدمة Cloud Shell بضع دقائق فقط.

7833d5e1c5d18f54.png

يتم تحميل هذا الجهاز الافتراضي مع جميع أدوات التطوير اللازمة. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح.

بعد الربط بخدمة Cloud Shell، من المفترض أن تتأكّد من أنّه تمّت مصادقتك وأنّ المشروع مضبوط على رقم تعريف مشروعك.

  1. شغِّل الأمر التالي في 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`
  1. شغّل الأمر التالي في Cloud Shell للتأكد من معرفة الأمر gcloud بمشروعك:
gcloud config list project

مخرجات الأمر

[core]
project = <PROJECT_ID>

إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:

gcloud config set project <PROJECT_ID>

مخرجات الأمر

Updated property [core/project].

3- إنشاء خدمات تشغيل السحابة الإلكترونية

إعداد متغيرات البيئة

يمكنك ضبط متغيّرات البيئة التي سيتم استخدامها خلال هذا الدرس التطبيقي حول الترميز.

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}`);
});

وأخيرًا، انشر خدمة تشغيل السحابة الإلكترونية من خلال تشغيل الأمر التالي.

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>

وأخيرًا، انشر خدمة تشغيل السحابة الإلكترونية من خلال تشغيل الأمر التالي.

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 التالي لدمج خدمة تشغيل في السحابة الإلكترونية في شبكتك الخاصة.

gcloud run services update $BACKEND --ingress internal --region $REGION

إذا كنت تحاول الاتصال بخدمة الخلفية من خدمة الواجهة الأمامية، ستتلقى رسالة الخطأ 404. ينتقل الاتصال الصادر (أو الخروج) من خدمة الواجهة الأمامية في السحابة الإلكترونية إلى الإنترنت أولاً، لذلك لا تعرف 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 الخاصة بإنشاء السمة special.googleapis.com، والتي يتم التعرّف عليها كعناوين IP داخلية. والآن، سيتم توجيه أي طلبات إلى هذه النطاقات عبر شبكة VPC.

يمكنك إجراء ذلك من خلال: https://cloud.google.com/run/docs/secring/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 التي تتيح الدخول الداخلي فقط (مثل الخلفية) مع الحفاظ على إمكانية الوصول العام إلى الإنترنت لخدمة الواجهة الأمامية

8. تَنظيم

لتجنُّب تحصيل رسوم غير مقصودة، (على سبيل المثال، إذا تم استدعاء خدمة Cloud Run هذه عن غير قصد أكثر من تخصيص استدعاء Cloud Run الشهري في الفئة المجانية)، يمكنك إما حذف خدمة Cloud Run أو حذف المشروع الذي أنشأته في الخطوة 2.

لحذف خدمات Cloud Run، انتقِل إلى Cloud Run Console على الرابط https://console.cloud.google.com/functions/ واحذف الخدمتَين $FRONTEND و $BACKEND اللتين أنشأتهما ضِمن هذا الدرس التطبيقي حول الترميز.

إذا اخترت حذف المشروع بالكامل، يمكنك الانتقال إلى https://console.cloud.google.com/cloud-resource-manager، واختيار المشروع الذي أنشأته في الخطوة الثانية، ثم اختيار "حذف". إذا حذفت المشروع، ستحتاج إلى تغيير المشاريع في حزمة تطوير البرامج (SDK) للسحابة الإلكترونية. يمكنك عرض قائمة بجميع المشاريع المتاحة من خلال تشغيل gcloud projects list.