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

1. Введение

Обзор

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

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

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

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

  • Как разрешить только трафик из VPC в ваш сервис Cloud Run
  • Как настроить выходной трафик в службе 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. Создайте сервисы 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.

Перейдите в каталог внешнего интерфейса.

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, а не из вашего браузера.

Вы увидите «Привет, мир».

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

Теперь попробуйте еще раз вызвать серверную службу из внешней службы.

На этот раз вы увидите «Привет, мир».

Примечание. Ваша клиентская служба не будет иметь доступа к Интернету, поскольку весь исходящий трафик направляется в VPC. Например, ваша клиентская служба истечет по тайм-ауту, если попытается получить доступ к https://curlmyip.org/.

6. Поздравляем!

Поздравляем с завершением работы над кодом!

Рекомендуем ознакомиться с документацией Cloud Run и о том, как настроить частную сеть для служб Cloud Run .

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

  • Как разрешить только трафик из VPC в ваш сервис Cloud Run
  • Как настроить выходной трафик в службе 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 .