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

۱. مقدمه

نمای کلی

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

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

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

آنچه یاد خواهید گرفت

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

۲. تنظیمات و الزامات

پیش‌نیازها

فعال کردن پوسته ابری

  1. از کنسول ابری، روی فعال کردن پوسته ابری کلیک کنید d1264ca30785e435.png .

cb81e7c8e34bc8d.png

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

d95252b003979716.png

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

7833d5e1c5d18f54.png

این ماشین مجازی مجهز به تمام ابزارهای توسعه مورد نیاز است. این ماشین یک دایرکتوری خانگی پایدار ۵ گیگابایتی ارائه می‌دهد و در فضای ابری گوگل اجرا می‌شود که عملکرد شبکه و احراز هویت را تا حد زیادی افزایش می‌دهد. بخش عمده‌ای از کار شما در این آزمایشگاه کد، اگر نگوییم همه، را می‌توان با یک مرورگر انجام داد.

پس از اتصال به 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].

۳. سرویس‌های Cloud Run را ایجاد کنید

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

شما می‌توانید متغیرهای محیطی که در سراسر این آزمایشگاه کد استفاده خواهند شد را تنظیم کنید.

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

سرویس Cloud Run بک‌اند را ایجاد کنید

ابتدا، یک دایرکتوری برای کد منبع ایجاد کنید و با دستور cd به آن دایرکتوری بروید.

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 ایجاد کنید

به دایرکتوری 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 را با موفقیت مستقر کرده‌اید.

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

در کادر متن، آدرس اینترنتی (URL) سرویس بک‌اند را وارد کنید. توجه داشته باشید که این درخواست به جای اینکه از مرورگر شما هدایت شود، از نمونه‌ی کلود ران (Cloud Run) در فرانت‌اند به سرویس کلود ران در بک‌اند هدایت می‌شود.

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

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

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

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

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

این بار با پیام «درخواست با کد وضعیت ۴۰۴ ناموفق بود» مواجه خواهید شد.

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

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

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

در این بخش، سرویس Cloud Run فرانت‌اند خود را برای ارتباط با سرویس بک‌اند از طریق یک 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

حالا دوباره سعی کنید سرویس بک‌اند خود را از سرویس فرانت‌اند فراخوانی کنید.

این بار عبارت "hello world" را خواهید دید.

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

۶. تبریک می‌گویم!

تبریک می‌گویم که آزمایشگاه کد را تمام کردید!

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

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

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

۷. تمیز کردن

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

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

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