Настройте службу Cloud Run для доступа как к внутренней службе Cloud Run, так и к общедоступному Интернету.

Настройте службу Cloud Run для доступа как к внутренней службе Cloud Run, так и к общедоступному Интернету.

О практической работе

subjectПоследнее обновление: февр. 14, 2024
account_circleАвтор: сотрудник Google

1. Введение

Обзор

Чтобы защитить сетевой трафик для своих служб и приложений, многие организации используют сеть виртуального частного облака (VCP) в Google Cloud с контролем периметра для предотвращения утечки данных. Сеть VPC — это виртуальная версия физической сети, реализованная внутри производственной сети Google. Сеть VPC обеспечивает подключение для ваших экземпляров виртуальной машины Compute Engine (VM), предлагает встроенные внутренние транзитные балансировщики сетевой нагрузки и прокси-системы для внутренних балансировщиков нагрузки приложений, подключается к локальным сетям с помощью туннелей 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. Затем вы увидите, как позвонить на https://curlmyip.org, чтобы получить IP-адрес вашей внешней службы.

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

  • Как разрешить только трафик из 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

Настройка переменных среды

Вы можете установить переменные среды, которые будут использоваться в этой лаборатории кода.

PROJECT_ID=<YOUR_PROJECT_ID>
REGION=<YOUR_REGION, e.g. us-central1>
FRONTEND=frontend-with-internet
BACKEND=backend
SUBNET_NAME=default

Создайте серверную службу Cloud Run.

Сначала создайте каталог для исходного кода и перейдите в этот каталог.

mkdir -p egress-private-codelab/frontend-w-internet egress-private-codelab/backend && cd egress-private-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-w-internet

Затем создайте файл 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",
    "htmx.org": "^1.9.10"
  }
}

Затем создайте исходный файл 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 Request Tester service on the Internet</h1>
      <form hx-trigger="submit" hx-post="/callService" hx-target="#zen">
        <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="zen" 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-адрес службы внешнего интерфейса в своем веб-браузере, например https://frontend-your-hash-uc.a.run.app/ .

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

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

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

Вы можете запустить следующую команду gcloud, чтобы включить службу Cloud Run в вашу частную сеть.

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

Если бы вы попытались вызвать серверную службу из внешней службы, вы получили бы ошибку 404. Исходящее (или выходное) соединение внешней службы Cloud Run сначала выходит в Интернет, поэтому Google Cloud не знает источник запроса.

5. Настройте службу внешнего интерфейса для доступа к VPC.

В этом разделе вы настроите интерфейсную службу Cloud Run для связи с внутренней службой через VPC.

Для этого вам необходимо добавить прямой выход VPC к вашей внешней службе Cloud Run, чтобы обеспечить доступ к внутренним IP-адресам в сети VPC. Затем вы настроите выход таким образом, чтобы в VPC направлялись только запросы к частным IP-адресам. Эта конфигурация позволит вашему интерфейсу по-прежнему иметь доступ к общедоступному Интернету. Подробнее о получении запросов от других сервисов Cloud Run можно узнать в документации.

Настройка прямого выхода VPC

Сначала запустите эту команду, чтобы использовать прямой выход VPC в вашей внешней службе:

gcloud beta run services update $FRONTEND \
--network=$SUBNET_NAME \
--subnet=$SUBNET_NAME  \
--vpc-egress=private-ranges-only \
--region=$REGION

Теперь вы можете подтвердить, что ваша клиентская служба имеет доступ к VPC:

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

Вы должны увидеть вывод, похожий на

VPC access:
    Network:        default
    Subnet:          default
    Egress:          private-ranges-only

Включить частный доступ Google

Затем вы включите частный доступ Google в подсети, выполнив следующую команду:

gcloud compute networks subnets update $SUBNET_NAME \
--region=$REGION \
--enable-private-ip-google-access

Вы можете проверить, включен ли частный доступ Google, выполнив следующую команду:

gcloud compute networks subnets describe $SUBNET_NAME \
--region=$REGION \
--format="get(privateIpGoogleAccess)"

Создайте зону Cloud DNS для URL-адресов run.app.

Наконец, создайте зону Cloud DNS для URL-адресов run.app, чтобы Google Cloud мог рассматривать их как внутренние IP-адреса.

На предыдущем шаге, когда вы настроили прямой выход VPC только для частных диапазонов. Это означает, что исходящие соединения из вашей внешней службы будут поступать в сеть VPC только в том случае, если местом назначения является внутренний IP-адрес. Однако ваша серверная служба использует URL-адрес run.app, который преобразуется в общедоступный IP-адрес.

На этом этапе вы создадите зону Cloud DNS для URL-адресов run.app, которые будут разрешаться в диапазоны IP-адресов Private.googleapis.com, которые распознаются как внутренние IP-адреса. Теперь любые запросы к этим диапазонам будут маршрутизироваться через вашу сеть VPC.

Вы можете сделать это: https://cloud.google.com/run/docs/securing/private-networking#from-other-services.

# do not include the https:// in your DNS Name
# for example: backend-<hash>-uc.a.run.app
DNS_NAME=<your backend service URL without the https://>

gcloud dns --project=$PROJECT_ID managed-zones create codelab-backend-service \
 --description="" \
 --dns-name="a.run.app." \
 --visibility="private" \
 --networks=$SUBNET_NAME

gcloud dns --project=$PROJECT_ID record-sets create $DNS_NAME. \
--zone="codelab-backend-service" \
 --type="A" \
 --ttl="60" \
--rrdatas="199.36.153.8,199.36.153.9,199.36.153.10,199.36.153.11"

Теперь, когда вы попытаетесь обратиться к серверной службе вашего веб-сайта, вы увидите сообщение «hello world».

А когда вы попытаетесь выйти в Интернет с помощью https://curlmyip.org/, вы увидите свой IP-адрес.

6. Поиск неисправностей

Вот некоторые возможные сообщения об ошибках, с которыми вы можете столкнуться, если настройки были настроены неправильно.

  • Если вы получили сообщение об ошибке getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.app убедитесь, что вы не добавили «https://» в запись DNS A.
  • Если вы получаете ошибку 404 при попытке доступа к серверной части после настройки зоны, вы можете либо дождаться истечения срока действия кеша глобальной записи run.app (например, 6 часов), либо создать новую ревизию (следовательно, очистив кеш). ), выполнив следующую команду: gcloud beta run services update $FRONTEND --network=$SUBNET_NAME --subnet=$SUBNET_NAME --vpc-egress=private-ranges-only --region=$REGION

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

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

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

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

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

8. Очистить

Чтобы избежать непреднамеренных расходов (например, если эта услуга Cloud Run случайно вызывается больше раз, чем выделено ежемесячное количество вызовов Cloud Run на уровне бесплатного пользования ), вы можете либо удалить службу Cloud Run, либо удалить проект, созданный на шаге 2.

Чтобы удалить службы Cloud Run, перейдите в облачную консоль Cloud Run по адресу https://console.cloud.google.com/functions/ и удалите службы $FRONTEND и $BACKEND, созданные вами в этой лаборатории кода.

Если вы решите удалить весь проект, вы можете перейти на https://console.cloud.google.com/cloud-resource-manager , выбрать проект, созданный на шаге 2, и нажать «Удалить». Если вы удалите проект, вам придется изменить проекты в Cloud SDK. Вы можете просмотреть список всех доступных проектов, запустив gcloud projects list .