Как настроить службу Cloud Run для доступа к внутренней службе Cloud Run с использованием прямого выхода VPC

1. Введение

Обзор

Для обеспечения безопасности сетевого трафика для своих сервисов и приложений многие организации используют виртуальную частную сеть (VPC) в Google Cloud с периметровым контролем для предотвращения утечки данных. Сеть VPC — это виртуальная версия физической сети, реализованная внутри производственной сети Google. Сеть VPC обеспечивает подключение для ваших виртуальных машин Compute Engine, предлагает собственные внутренние балансировщики нагрузки и прокси-системы для внутренних балансировщиков нагрузки приложений, подключается к локальным сетям с помощью туннелей Cloud VPN и VLAN-подключений для Cloud Interconnect, а также распределяет трафик от внешних балансировщиков нагрузки Google Cloud на бэкэнды.

В отличие от виртуальных машин, сервисы Cloud Run по умолчанию не привязаны к какой-либо конкретной сети VPC. В этом практическом занятии показано, как изменить настройки входящих соединений таким образом, чтобы доступ к сервису Cloud Run (например, к бэкэнд-сервису) имели только соединения, поступающие из VPC. Кроме того, в этом практическом занятии показано, как обеспечить доступ второго сервиса (например, фронтенд-сервиса) к бэкэнд-сервису Cloud Run через VPC.

В этом примере бэкэнд-сервис Cloud Run возвращает сообщение "hello world". Фронтенд-сервис Cloud Run предоставляет поле ввода в пользовательском интерфейсе для получения URL-адреса. Затем фронтенд-сервис отправляет GET-запрос к этому URL-адресу (например, к бэкэнд-сервису), таким образом, это запрос между сервисами (а не запрос между браузером и сервисом). Когда фронтенд-сервис успешно связывается с бэкэндом, в браузере отображается сообщение "hello world".

Что вы узнаете

  • Как разрешить доступ к сервису Cloud Run только трафику из VPC.
  • Как настроить исходящий трафик в сервисе Cloud Run для взаимодействия с сервисом Cloud Run, имеющим только внутренний входящий трафик.

2. Настройка и требования

Предварительные требования

Активировать Cloud Shell

  1. В консоли Cloud нажмите «Активировать Cloud Shell» . d1264ca30785e435.png .

cb81e7c8e34bc8d.png

Если вы запускаете Cloud Shell впервые, вам будет показан промежуточный экран с описанием его возможностей. Если вы увидели промежуточный экран, нажмите «Продолжить» .

d95252b003979716.png

Подготовка и подключение к Cloud Shell займут всего несколько минут.

7833d5e1c5d18f54.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, ваша работа в этом практическом задании может быть выполнена с помощью браузера.

После подключения к 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. Создайте службы 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.

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

Вызов бэкэнд-сервиса

Убедитесь, что вы успешно развернули две службы Cloud Run.

Откройте URL-адрес внешнего интерфейса сервиса в своем веб-браузере.

В текстовом поле введите URL-адрес серверной службы. Обратите внимание, что этот запрос направляется с внешнего экземпляра Cloud Run на серверную службу Cloud Run, а не из вашего браузера.

Вы увидите надпись «hello world».

4. Настройте серверную службу только для внутреннего входящего трафика.

Выполните следующую команду gcloud, чтобы разрешить доступ к вашему бэкэнд-сервису только трафику из вашей VPC-сети.

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

Чтобы убедиться, что ваш бэкэнд-сервис может принимать трафик только из вашей VPC, попробуйте еще раз вызвать ваш бэкэнд-сервис из вашего фронтенд-сервиса.

На этот раз вы увидите сообщение "Запрос не выполнен с кодом состояния 404".

Эта ошибка возникла потому, что исходящий запрос (т.е. egress) от фронтенд-сервиса 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. Поздравляем!

Поздравляем с завершением практического занятия!

Мы рекомендуем ознакомиться с документацией Cloud Run и инструкцией по настройке частной сети для сервисов Cloud Run .

Что мы рассмотрели

  • Как разрешить доступ к сервису Cloud Run только трафику из VPC.
  • Как настроить исходящий трафик в сервисе Cloud Run для взаимодействия с сервисом Cloud Run, имеющим только внутренний входящий трафик.

7. Уборка

Чтобы избежать непреднамеренных списаний средств (например, если сервисы 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 , выберите проект, созданный на шаге 2, и нажмите «Удалить». После удаления проекта вам потребуется изменить проекты в вашем Cloud SDK. Список всех доступных проектов можно просмотреть, выполнив gcloud projects list .