كيفية ضبط خدمة "تشغيل في السحابة الإلكترونية" للوصول إلى خدمة داخلية في السحابة الإلكترونية باستخدام الخروج المباشر من شبكة VPC

1. مقدمة

نظرة عامة

لتأمين حركة بيانات الشبكة لخدماتها وتطبيقاتها، تستخدم العديد من المؤسسات شبكة سحابة إلكترونية خاصة افتراضية (VPC) على 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 هذا (مثل خدمة الخلفية)، مما يجعل هذا الطلب خدمة لطلب خدمة (بدلاً من طلب من متصفح إلى خدمة). عندما تتمكن خدمة الواجهة الأمامية من الوصول إلى الواجهة الخلفية بنجاح، يتم عرض رسالة "مرحبًا" في المتصفِّح.

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

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

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

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

REGION=<YOUR_REGION, e.g. us-central1>
FRONTEND=frontend
BACKEND=backend

إنشاء خدمة Cloud Run في الخلفية

أولاً، أنشئ دليلاً لرمز المصدر والقرص المضغوط في هذا الدليل.

mkdir -p internal-codelab/frontend internal-codelab/backend && cd internal-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

بعد ذلك، أنشِئ ملف 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"
  }
}

بعد ذلك، أنشِئ ملف مصدر 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 Frontend service on the Internet</h1>
      <form hx-trigger="submit" hx-post="/callService" hx-target="#message">
        <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="message" style="white-space: pre-wrap"></div>
        <p></p>
      </form>
    </div>
  </body>
</html>

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

gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION

الاتصال بخدمة الخلفية

تحقق من نشر خدمتين من خدمات تشغيل السحابة الإلكترونية بنجاح.

افتح عنوان URL لخدمة الواجهة الأمامية في متصفح الويب.

في مربع النص، أدخِل عنوان URL لخدمة الخلفية. تجدر الإشارة إلى أنّه يتم توجيه هذا الطلب من مثيل Cloud Run في الواجهة الأمامية إلى خدمة Cloud Run التي تعمل في الخلفية، بدلاً من توجيهه من المتصفّح.

ستظهر لك عبارة "hello world".

4. ضبط خدمة الخلفية للدخول الداخلي فقط

شغِّل الأمر gcloud التالي للسماح بحركة البيانات من داخل شبكة VPC فقط للوصول إلى خدمة الخلفية.

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

للتأكّد من أنّ الخدمة الخلفية لا يمكنها تلقّي زيارات إلا من شبكة VPC، حاوِل الاتصال بخدمة الخلفية مرة أخرى من خدمة الواجهة الأمامية.

ستظهر لك هذه المرة رسالة "فشل الطلب برمز الحالة 404"

لقد تلقّيت هذا الخطأ لأنّ طلب الصادر في خدمة Cloud Run (أي الخروج) في الواجهة الأمامية يخرج إلى الإنترنت أولاً، لذلك لا تعرف Google Cloud مصدر الطلب.

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

5- اضبط إعدادات خدمة الواجهة الأمامية للوصول إلى VPC.

في هذا القسم، يمكنك إعداد خدمة Cloud Run في الواجهة الأمامية للاتصال بخدمة الخلفية من خلال سحابة VPC.

لإجراء ذلك، عليك إضافة مَخرج مباشر من شبكة VPC إلى مثيلات Cloud Run في الواجهة الأمامية لمنح الخدمة عنوان IP داخليًا لاستخدامه في شبكة VPC. بعد ذلك، عليك ضبط الخروج بحيث يتم نقل جميع الاتصالات الصادرة من خدمة الواجهة الأمامية إلى VPC.

أولاً، شغِّل الأمر التالي لتفعيل الخروج المباشر من شبكة VPC:

gcloud beta run services update $FRONTEND \
--network=default \
--subnet=default \
--vpc-egress=all-traffic \
--region=$REGION

يمكنك الآن التأكّد من إمكانية وصول خدمة الواجهة الأمامية إلى VPC:

gcloud beta run services describe $FRONTEND \
--region=$REGION

يُفترض أن تظهر لك نتيجة مشابهة

VPC access:
    Network:         default
    Subnet:          default
    Egress:          all-traffic

حاول الآن الاتصال بخدمة الخلفية مرة أخرى من خدمة الواجهة الأمامية.

هذه المرة سترى "hello world".

ملاحظة: لن يتوفّر اتصال بالإنترنت لخدمة الواجهة الأمامية لأنّه تم توجيه جميع مصادر البيانات إلى شبكة VPC. على سبيل المثال، ستنتهي مهلة خدمة الواجهة الأمامية إذا حاولَت الوصول إلى https://curlmyip.org/.

6- تهانينا

تهانينا على إكمال الدرس التطبيقي حول الترميز.

نقترح مراجعة مستندات تشغيل السحابة الإلكترونية وكيفية ضبط الشبكات الخاصة لخدمات التشغيل في السحابة الإلكترونية.

النقاط التي تناولناها

  • كيفية السماح بالزيارات من شبكة VPC فقط إلى خدمة تشغيل السحابة الإلكترونية
  • كيفية ضبط الخروج في خدمة Cloud Run للاتصال بخدمة Cloud Run الداخلية فقط

7. تَنظيم

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

لحذف خدمة Cloud Run، انتقِل إلى Cloud Run Console على https://console.cloud.google.com/run واحذف الخدمتَين $FRONTEND و $BACKEND.

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