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". Затем вы увидите, как можно обратиться к https://curlmyip.org, чтобы получить IP-адрес вашего фронтенд-сервиса.
Что вы узнаете
- Как разрешить доступ к сервису Cloud Run только трафику из VPC.
- Как настроить исходящий трафик для сервиса Cloud Run (например, фронтенда) для связи с сервисом Cloud Run, имеющим только внутренний трафик (например, бэкендом), сохраняя при этом доступ к общедоступному Интернету для фронтенд-сервиса.
2. Настройка и требования
Предварительные требования
- Вы вошли в облачную консоль.
- Вы уже развернули функцию второго поколения. Например, для начала работы вы можете воспользоваться инструкцией по быстрому развертыванию облачной функции второго поколения .
Активировать Cloud Shell
- В консоли Cloud нажмите «Активировать Cloud Shell» .
.

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

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

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, ваша работа в этом практическом задании может быть выполнена с помощью браузера.
После подключения к Cloud Shell вы увидите, что прошли аутентификацию и что проект настроен на ваш идентификатор проекта.
- Выполните следующую команду в 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`
- Выполните следующую команду в 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.
Сначала создайте директорию для исходного кода и перейдите в неё с помощью команды `cd`.
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 для внешнего интерфейса.
Перейдите в каталог frontend.
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, а не из вашего браузера.
Вы увидите надпись «hello world».
4. Настройте серверную службу только для внутреннего входящего трафика.
Для интеграции сервиса Cloud Run в вашу частную сеть можно выполнить следующую команду gcloud.
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 на использование только частных диапазонов IP-адресов. Это означает, что исходящие соединения от вашего фронтенд-сервиса будут направляться в сеть 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 .
Что мы рассмотрели
- Как разрешить доступ к сервису Cloud Run только трафику из VPC.
- Как настроить исходящий трафик для сервиса 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 .