نحوه پیکربندی یک سرویس Cloud Run برای دسترسی به سرویس داخلی Cloud Run با استفاده از خروج مستقیم VPC

1. مقدمه

نمای کلی

بسیاری از سازمان‌ها برای ایمن‌سازی ترافیک شبکه برای سرویس‌ها و برنامه‌های خود، از یک شبکه Virtual Private Cloud (VPC) در Google Cloud با کنترل‌های محیطی برای جلوگیری از نفوذ داده‌ها استفاده می‌کنند. شبکه VPC یک نسخه مجازی از یک شبکه فیزیکی است که در داخل شبکه تولید گوگل پیاده سازی شده است. یک شبکه VPC اتصال را برای نمونه‌های ماشین مجازی موتور محاسباتی (VM) شما فراهم می‌کند، تعادل‌دهنده بار داخلی و سیستم‌های پراکسی را برای متعادل‌کننده‌های بار داخلی برنامه ارائه می‌دهد، با استفاده از تونل‌های Cloud VPN و پیوست‌های VLAN برای Cloud Interconnect، به شبکه‌های داخلی متصل می‌شود. و ترافیک را از متعادل کننده های بار خارجی Google Cloud به backend ها توزیع می کند.

بر خلاف ماشین های مجازی، سرویس های Cloud Run به طور پیش فرض با هیچ شبکه VPC خاصی مرتبط نیستند. این آزمایشگاه کد نحوه تغییر تنظیمات ورودی (اتصالات ورودی) را به گونه ای نشان می دهد که فقط ترافیکی که از VPC می آید می تواند به یک سرویس Cloud Run (به عنوان مثال یک سرویس باطن) دسترسی داشته باشد. علاوه بر این، این کد لبه به شما نشان می دهد که چگونه می توانید یک سرویس دوم (به عنوان مثال یک سرویس frontend) از طریق VPC به سرویس پشتیبان Cloud Run دسترسی داشته باشید.

در این مثال، سرویس Cloud Run باطن، hello world را برمی‌گرداند. سرویس فرانت‌اند Cloud Run یک فیلد ورودی در رابط کاربری برای جمع‌آوری URL ارائه می‌کند. سپس سرویس frontend یک درخواست GET به آن URL (مثلاً سرویس Backend) می‌کند، از این رو این درخواست سرویس به سرویس (به جای درخواست مرورگر به سرویس) می‌شود. هنگامی که سرویس frontend می تواند با موفقیت به backend برسد، پیام hello world در مرورگر نمایش داده می شود.

چیزی که یاد خواهید گرفت

  • چگونه می توان فقط از VPC به سرویس Cloud Run خود اجازه ترافیک داد
  • نحوه پیکربندی egress در یک سرویس Cloud Run برای برقراری ارتباط با یک سرویس Cloud Run فقط ورودی داخلی

2. راه اندازی و الزامات

پیش نیازها

Cloud Shell را فعال کنید

  1. از Cloud Console، روی Activate Cloud Shell کلیک کنید d1264ca30785e435.png .

cb81e7c8e34bc8d.png

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

d95252b003979716.png

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

7833d5e1c5d18f54.png

این ماشین مجازی با تمام ابزارهای توسعه مورد نیاز بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی ارائه می‌کند و در Google Cloud اجرا می‌شود، که عملکرد و احراز هویت شبکه را بسیار افزایش می‌دهد. بسیاری از کارهای شما، اگر نه همه، در این کد لبه با مرورگر قابل انجام است.

پس از اتصال به Cloud Shell، باید ببینید که احراز هویت شده اید و پروژه به ID پروژه شما تنظیم شده است.

  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. خدمات Cloud Run را ایجاد کنید

تنظیم متغیرهای محیطی

می توانید متغیرهای محیطی را تنظیم کنید که در سراسر این کد لبه مورد استفاده قرار می گیرند.

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

در نهایت، سرویس Cloud Run را با اجرای دستور زیر اجرا کنید.

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

سرویس فرانت اند Cloud Run را ایجاد کنید

به دایرکتوری frontend بروید.

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>

در نهایت، سرویس Cloud Run را با اجرای دستور زیر اجرا کنید.

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

با سرویس Backend تماس بگیرید

بررسی کنید که دو سرویس Cloud Run را با موفقیت اجرا کرده اید.

URL سرویس frontend را در مرورگر وب خود باز کنید.

در جعبه متن، URL مربوط به سرویس Backend را وارد کنید. توجه داشته باشید که این درخواست به جای اینکه از مرورگر شما هدایت شود، از نمونه Cloud Run جلویی به سرویس Cloud Run هدایت می شود.

"سلام دنیا" را خواهید دید.

4. سرویس Backend را فقط برای ورود داخلی تنظیم کنید

دستور gcloud زیر را اجرا کنید تا فقط به ترافیک از داخل شبکه VPC شما اجازه دسترسی به سرویس باطن شما را بدهد.

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

برای تأیید اینکه سرویس باطن شما فقط می‌تواند از VPC شما ترافیک دریافت کند، دوباره سعی کنید با سرویس باطن خود از سرویس frontend خود تماس بگیرید.

این بار "درخواست با کد وضعیت 404 ناموفق" را مشاهده خواهید کرد.

شما این خطا را دریافت کردید زیرا درخواست خروجی سرویس Cloud Run (یعنی خروج) ابتدا به اینترنت می رود، بنابراین Google Cloud منشأ درخواست را نمی داند.

در بخش بعدی، سرویس frontend را برای دسترسی به VPC پیکربندی می‌کنید، بنابراین Google Cloud متوجه می‌شود که درخواست از VPC که به عنوان یک منبع داخلی شناخته می‌شود، آمده است.

5. سرویس Frontend را برای دسترسی به VPC پیکربندی کنید

در این بخش، سرویس Cloud Run frontend خود را برای ارتباط با سرویس باطن خود از طریق VPC پیکربندی خواهید کرد.

برای انجام این کار، باید خروج مستقیم VPC را به نمونه‌های Cloud Run frontend خود اضافه کنید تا به سرویس خود یک IP داخلی برای استفاده در VPC بدهید. سپس، خروجی را طوری پیکربندی خواهید کرد که تمام اتصالات خروجی از سرویس frontend به VPC بروند.

ابتدا این دستور را اجرا کنید تا خروج مستقیم VPC فعال شود:

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

اکنون می توانید تأیید کنید که سرویس frontend شما به VPC دسترسی دارد:

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

شما باید خروجی مشابه را ببینید

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

اکنون دوباره سعی کنید با سرویس باطن خود از سرویس frontend خود تماس بگیرید.

این بار «سلام دنیا» را خواهید دید.

توجه: سرویس frontend شما به اینترنت دسترسی نخواهد داشت زیرا تمام خروجی ها به VPC هدایت شده اند. به عنوان مثال، اگر سرویس frontend شما سعی کند به https://curlmyip.org/ دسترسی پیدا کند، مهلت زمانی خواهد داشت.

6. تبریک!

برای تکمیل کد لبه تبریک می گویم!

توصیه می‌کنیم مستندات Cloud Run و نحوه پیکربندی شبکه خصوصی برای سرویس‌های Cloud Run را مرور کنید.

آنچه را پوشش داده ایم

  • چگونه می توان فقط از VPC به سرویس Cloud Run خود اجازه ترافیک داد
  • نحوه پیکربندی egress در یک سرویس Cloud Run برای برقراری ارتباط با یک سرویس Cloud Run فقط ورودی داخلی

7. پاکسازی کنید

برای جلوگیری از هزینه‌های غیرعمدی، (به عنوان مثال، اگر سرویس‌های Cloud Run به طور ناخواسته بیشتر از تخصیص فراخوانی ماهانه Cloud Run در ردیف رایگان فراخوانی می‌شوند)، می‌توانید Cloud Run را حذف کنید یا پروژه‌ای را که در مرحله 2 ایجاد کرده‌اید حذف کنید.

برای حذف سرویس Cloud Run، به کنسول Cloud Run Cloud در https://console.cloud.google.com/run بروید و خدمات $FRONTEND و $BACKEND را حذف کنید.

اگر تصمیم به حذف کل پروژه دارید، می‌توانید به https://console.cloud.google.com/cloud-resource-manager بروید، پروژه‌ای را که در مرحله ۲ ایجاد کرده‌اید انتخاب کنید و حذف را انتخاب کنید. اگر پروژه را حذف کنید، باید پروژه ها را در Cloud SDK خود تغییر دهید. با اجرای gcloud projects list می توانید لیست تمام پروژه های موجود را مشاهده کنید.