Развертывание статического веб-сайта в отказоустойчивой конфигурации в Yandex Cloud
- Общая архитектура решений
- Обзор вариантов решений
- Бакет Yandex Object Storage с публичным доступом
- Бакет Yandex Object Storage с публичным доступом и раздачей контента через Yandex Cloud CDN
- Бакет Yandex Object Storage без публичного доступа с Yandex API Gateway и раздачей контента через Yandex Cloud CDN
- Бакет Yandex Object Storage без публичного доступа с Yandex Application Load Balancer
Настоящее руководство содержит несколько вариантов решений по развертыванию в инфраструктуре Yandex Cloud статического веб-сайта с динамическими элементами (например, формой регистрации или сбора заявок и т.п.) в отказоустойчивой конфигурации.
Предлагаемые решения позволяют оптимизировать расходы, а также обеспечивают высокую скорость загрузки сайта на стороне конечных пользователей.
Общая архитектура решений
В основе инфраструктуры, используемой всеми рассматриваемыми решениями, лежат сервисы Yandex Object Storage и Yandex Virtual Private Cloud. Для ускорения загрузки контента у конечных пользователей используются ресурсы сервиса Yandex Cloud CDN. Кроме этого, разные варианты решений используют различные комбинации вспомогательных сервисов экосистемы Yandex Cloud: Yandex Cloud DNS, Yandex Certificate Manager, Yandex API Gateway, Yandex Application Load Balancer, Yandex Cloud Postbox и Yandex Cloud Functions.
Отказоустойчивость рассматриваемых решений обеспечивается за счет автоматической репликации данных, сохраняемых в бакетах Object Storage, а также за счет опциональной возможности включения версионирования.
Плюсы предлагаемых решений:
- не нужно проектировать отказоустойчивое размещение сайта одновременно в нескольких зонах доступности, так как используемые сервисы изначально обеспечивают надежность и отказоустойчивость;
- относительная простота архитектуры;
- относительно невысокая стоимость решений по сравнению с другими способами размещения, а также возможность нетарифицируемого использования (
free tier), позволяющая практически бесплатно получить решения для проектов с небольшим объемом данных и малым количеством посетителей.
Автоматическое развертывание инфраструктуры
В дополнительных материалах к руководству содержатся примеры конфигурации Terraform, которые позволяют развернуть необходимую облачную инфраструктуру максимально быстро и содержат примеры решения типовых задач, таких как:
- загрузка и обновление файлов статического сайта в Object Storage;
- создание сертификата от Let's Encrypt для сайта в Certificate Manager;
- настройка сервиса Yandex Cloud Postbox для отправки транзакционных писем;
- внедрение на сайт функции Cloud Functions для отправки писем и пример такой функции для среды Node.js
.
Дополнительные материалы к руководству доступны в репозитории
Обзор вариантов решений
В зависимости от требований, предъявляемых к сайту, системная архитектура решений может существенно различаться. При этом для всех вариантов размещения необходимо собственное доменное имя сайта, корректно настроенный DNS для домена, а также SSL-сертификат.
В настоящем обзоре рассматриваются следующие варианты решений по размещению статического сайта в инфраструктуре Yandex Cloud:
- Бакет Yandex Object Storage с публичным доступом
- Бакет Yandex Object Storage с публичным доступом и раздачей контента через Yandex Cloud CDN
- Бакет Yandex Object Storage без публичного доступа с Yandex API Gateway и раздачей контента через Yandex Cloud CDN
- Бакет Yandex Object Storage без публичного доступа с Yandex Application Load Balancer
Бакет Yandex Object Storage с публичным доступом
В бакетах Yandex Object Storage предусмотрен специальный режим Хостинг, являющийся одним из самых простых и доступных способов размещения статического сайта в Yandex Cloud. Для небольших проектов дополнительным плюсом такого размещения является возможность нетарифицируемого использования (free tier). Подробнее о нетарифицируемом использовании сервиса Object Storage читайте в документации Yandex Cloud Billing.
Схема работы решения:
Необходимые ресурсы
Чтобы разместить статический сайт в этом варианте решения, потребуются:
- бакет Object Storage с включенным режимом
Хостинг; - доменное имя и SSL-сертификат, выпущенный для этого доменного имени;
- настроенная публичная зона DNS для домена и ресурсная запись, связывающая бакет и доменное имя.
Примечание
Для того чтобы к сайту можно было обращаться по доменному имени, имя бакета должно совпадать с этим доменным именем. Например: my.example.com.
Пошагово процесс настройки статического сайта с использованием бакета Object Storage с публичным доступом и включенным режимом Хостинг описан в разделе Статический сайт в Yandex Object Storage.
Преимущества и недостатки этого варианта решения
|
Преимущества |
Недостатки |
|
|
Избавиться от указанных выше недостатков позволяют другие варианты развертывания.
Нюансы при реализации решения
При развертывании сайта учитывайте следующие нюансы:
-
Тип ресурсной DNS-записи, связывающей доменное имя и бакет, зависит от уровня домена:
- Для доменов второго уровня (например,
example.com) создайте ресурсную запись ANAME. - Для доменов третьего уровня и выше (например,
my.example.com,my.other.example.comи т.д.) создайте ресурсную запись CNAME.
Примечание
Ресурсная запись в любом случае должна указывать на служебный домен бакета.
Например, для домена
my.example.comв публичной DNS-зонеexample.comсоздайте CNAME-записьmy, указывающую наmy.example.com.website.yandexcloud.net.Точка в конце целевого доменного имени обязательна, ее отсутствие приведет к неработоспособности сайта.
Подробнее о том, как создать ресурсную запись, читайте в разделе Создать ресурсную запись.
- Для доменов второго уровня (например,
-
Сервис Object Storage интегрирован с сервисом Certificate Manager, который поддерживает работу как с пользовательскими сертификатами, так и с сертификатами от Let's Encrypt.
При создании сертификата от Let's Encrypt пройдите проверку прав на домен. Наиболее надежным и удобным способом проверки является DNS-проверка с использованием CNAME-записи. Такая проверка выполняется один раз и в дальнейшем не требует участия пользователя для перевыпуска сертификата.
Подробнее о том, как пройти проверку прав владения доменом, читайте в разделе Проверить права на домены.
-
Работа в режиме
Хостингтребует включения публичного доступа к бакету и предоставляет ряд дополнительных возможностей.Дополнительные возможности бакета в режиме
Хостинг-
Запросы к пути
/возвращают содержимое файла, заданного в параметре Главная страница. -
Запросы к несуществующим объектам возвращают содержимое файла, заданного в параметре Страница ошибки.
-
Доступна дополнительная функциональность переадресации запросов.
-
Служебный домен настраивается для обработки запросов к основному домену по протоколу
https. -
Служебный домен бакета с включенным режимом
Хостинг—website.yandexcloud.net.Примечание
Если режим
Хостингвыключен, то служебный домен бакета —storage.yandexcloud.net.
-
-
Если в качестве имени бакета используется доменное имя с точками, обращение к служебному домену бакета в формате
<доменное_имя>.website.yandexcloud.netпо протоколуhttpsневозможно. Это связано с тем, что служебный домен в этом формате использует wildcard-сертификат SSL, который подходит только для доменов четвертого уровня*.website.yandexcloud.net.Поэтому в таких случаях для обращения к служебному домену бакета по протоколу
httpsиспользуйте URL в форматеhttps://website.yandexcloud.net/<доменное_имя>.Например:
https://website.yandexcloud.net/my.example.com. -
Доступ к содержимому бакета может быть ограничен с помощью политик доступа. Но такие политики не всегда позволяют легко решать практические задачи. Например, можно ограничить доступ к содержимому бакета для определенного диапазона IP-адресов, но нельзя задать такие ограничения для доменных имен.
Подробнее о том, как настроить политику доступа для бакета, читайте в разделе Управление политикой доступа (bucket policy).
-
При загрузке объектов в бакет можно задать ряд заголовков, позволяющих управлять обработкой контента. Например, заголовок
Content-Typeпозволяет задать MIME-тип содержимого.Также существует еще ряд заголовков, которые можно установить для объектов в бакете Object Storage и которые позволяют управлять обработкой контента в браузере.
Наиболее востребованные заголовки
-
Content-Type— позволяет задать MIME-тип содержимого объекта в бакете. -
Cache-Control— управляет кешированием на клиенте и промежуточных кеширующих серверах. Иногда установка параметров кеширования на клиенте позволяет значительно ускорить загрузку страниц и снизить потребление трафика.Важно
С осторожностью используйте заголовок
Cache-Controlдля установки параметров кеширования, особенно в отношении HTML-страниц. Клиент может на длительный срок закешировать ошибочную страницу, в результате чего браузер будет отображать пользователю неверную информацию до тех пор, пока не истечет срок кеширования или пользователь вручную не очистит кеш браузера. -
Content-Disposition— сообщает браузеру, что объект должен сохраняться как файл, и задает конкретное имя файла. -
Content-Encoding— указывает метод, которым закодирован файл (например, сжатиеgzip).
Подробнее о том, как задать заголовки для объектов в бакете, читайте в разделе Решение проблем.
-
Решение проблем
Из-за особенностей работы Object Storage содержимое сайта будет доступно не только по основному адресу my.example.com, но и через служебные домены Object Storage:
my.example.com.website.yandexcloud.net;website.yandexcloud.net/my.example.com;storage.yandexcloud.net/my.example.com.
С точки зрения алгоритмов поисковых систем между этими адресами может возникнуть конкуренция, что негативно скажется на ранжировании сайта в поисковой выдаче.
Подробнее об этой проблеме и о том, как ее решить, читайте в документации к сервису Яндекс Вебмастер
Такое поведение может быть вызвано некорректным заголовком Content-Type в метаданных проблемных объектов в бакете. Если при загрузке объекта в бакет не задать значение этого заголовка явным образом, Object Storage попытается самостоятельно определить тип загружаемого контента. Значение заголовка Content-Type, определенное сервисом автоматически, иногда может не соответствовать ожиданиям пользователя.
Рекомендуем явно задавать значение для заголовка Content-Type при загрузке файлов статического сайта в бакет:
- Чтобы страница сайта открывалась, а не скачивалась, заголовок должен иметь значение
text/html. - Чтобы скрипт
JavaScriptзапускался, заголовок должен иметь значениеapplication/javascript.
Пример использования Yandex Cloud CLI для загрузки объекта с установкой нужного типа контента.
yc storage s3api put-object \
--bucket my.example.com \
--key index.html \
--body /path/to/my/index.html \
--content-type 'text/html'
Пример конфигурации Terraform для автоматизации загрузки файлов сайта с указанием Content-Type для каждого объекта на основании его расширения.
variable "site_source_dir" {
type = string
description = "Site source directory" # Локальная директория с файлами сайта
default = "~/path/to/my/site" # Используйте функцию pathexpand() для обработки ~ и других специальных символов
}
locals {
site_mime_types = jsondecode(file("mime.json")) # Файл с таблицей сопоставления расширений файлов с Mime-типом
}
resource "yandex_storage_object" "files" {
for_each = var.site_source_dir == null ? toset([]) : fileset(pathexpand(var.site_source_dir), "**") # рекурсивный перебор всех файлов в каталоге
bucket = "my.example.com"
key = each.key
source = pathexpand("${var.site_source_dir}/${each.key}")
source_hash = filemd5(pathexpand("${var.site_source_dir}/${each.key}")) # Хранение дайджеста файла в стейте, чтобы файл перезагружался после изменения
content_type = lookup(local.site_mime_types, regex("\\.[^.]+$", each.key), null) # Выставление Content-Type для файла в зависимости от его расширения
}
Пример содержимого файла mime.json:
{
".html": "text/html",
".htm": "text/html",
".shtml": "text/html",
".css": "text/css",
".xml": "text/xml",
".gif": "image/gif",
...
}
О том, как изменить тип контента для группы уже загруженных в бакет объектов, читайте в разделе Устранение проблем с некорректным MIME-типом объектов при их загрузке в Object Storage.
Бакет Yandex Object Storage с публичным доступом и раздачей контента через Yandex Cloud CDN
В этом варианте решения бакет в режиме хостинга используется в качестве источника для CDN-ресурса Cloud CDN. Доменное имя сайта связывается с помощью ресурсной записи CNAME со специальным доменным именем CDN-провайдера, которое присваивается каталогу пользователя в облаке Yandex Cloud.
CDN-ресурс кеширует запросы конечных пользователей на своих серверах, а к бакету-источнику обращается только в том случае, когда нужного файла нет в кеше.
Основное преимущество CDN — геораспределенность. Точки присутствия CDN расположены в больших городах, максимально близко к основным потребителям контента. За счет кеширования и сокращения расстояния между клиентом и CDN-сервером сайт быстрее загружается в браузере конечного пользователя.
Примечание
Не используйте ресурсную запись ANAME с доменными именами для раздачи контента, поскольку в таком случае конечный пользователь получит ответ от CDN-сервера, не связанного с геолокацией пользователя. Ответ всегда будет одинаков для всех пользователей.
Схема работы решения для полностью статического сайта:
Необходимые ресурсы
Чтобы разместить статический сайт в этом варианте решения, потребуются:
- бакет Object Storage с включенным режимом
Хостинг; - CDN-ресурс Cloud CDN;
- доменное имя и SSL-сертификат, выпущенный для этого доменного имени;
- настроенная публичная зона DNS для домена и ресурсная запись, связывающая CDN-ресурс и доменное имя.
Подробнее о том, как создать CDN-ресурс, читайте в разделе Создание ресурса.
Преимущества и недостатки этого варианта решения
|
Преимущества |
Недостатки |
|
|
Таким образом, если содержимое сайта подходит для кеширования (а статические сайты, как правило, хорошо для этого подходят) и при настройке учитываются особенности работы с поисковыми системами, то появляется возможность добиться существенной экономии в расходах на доставку трафика, повысить доступность сайта для конечных пользователей и, как следствие, значительно улучшить клиентский опыт.
Решение проблем
Предлагаемое решение позволяет ограничить доступ к бакету, разрешив его только для хостов Cloud CDN. Это запретит индексацию сайта поисковыми системами по служебным доменам бакета.
Предоставить доступ к бакету только для хостов Cloud CDN можно несколькими способами:
-
С помощью политик доступа открыть доступ к бакету только из подсетей Cloud CDN.
Актуальный список таких подсетей доступен публично
.Важно
Список подсетей Cloud CDN может изменяться, поэтому при использовании этого способа ограничения доступа к бакету отслеживайте такие изменения и своевременно вносите изменения в разрешающие правила доступа.
Подробнее читайте в разделе Как ограничить доступ к бакету Object Storage диапазоном IP-адресов, принадлежащих Cloud CDN.
-
Чтобы избежать необходимости постоянно отслеживать изменения в списке подсетей Cloud CDN, можно использовать экранирование источников, при этом с помощью политик доступа нужно предоставить доступ к бакету только для подсетей, которые используются для экранирования источников:
188.72.110.0/24;188.72.111.0/24.
Список этих подсетей более стабилен и менее подвержен изменениям.
Подробнее о том, как настроить политику доступа для бакета, читайте в разделе Управление политикой доступа (bucket policy).
Предлагаемое решение позволяет устанавливать в рамках одного домена разные источники данных, параметры кеширования и другие настройки в зависимости от пути к запрашиваемому объекту, в том числе по маске. Для этого используются локационные правила.
Правила обработки запросов задаются с помощью регулярных выражений, на соответствие которым проверяется путь запрашиваемого объекта. Для каждого правила можно указать:
- источник контента — бакет, L7-балансировщик или произвольный сервер;
- параметры хранения контента в CDN и параметры кеширования для клиента;
- правила модификации и перенаправления запросов;
- значения заголовков CORS.
Правила обработки запросов позволяют настраивать также и другие параметры. Подробнее читайте в разделах Локационные правила Yandex Cloud CDN и Настроить локационные правила Yandex Cloud CDN.
Задачей статических сайтов зачастую является привлечение пользователей с тем, чтобы они совершали на этих сайтах определенные целевые действия — переход по ссылке или заполнение регистрационной формы.
Используя локационные правила, можно создать достаточно сложный сайт, содержащий как статические, так и динамические разделы (например, регистрационные формы).
Важно
По умолчанию в Cloud CDN HTTP-методы POST, PUT, PATCH и DELETE недоступны в запросах клиентов. Чтобы получить возможность их использования, создайте обращение
Нагрузка на обработчик данных регистрационных форм обычно носит неравномерный характер и может варьироваться от периодов длительного простоя до необходимости обрабатывать сотни запросов в секунду.
В таких обстоятельствах удобным инструментом обработки запросов являются функции Yandex Cloud Functions. Вызывать функции со страниц сайта можно с помощью API-шлюза Yandex API Gateway.
[Вызов](*function_call) функции осуществляется по специальному URL функции https://functions.yandexcloud.net/<идентификатор_функции>. При этом попытка прямого вызова функции со страницы сайта в браузере завершится ошибкой: браузер заблокирует запрос, поскольку у URL функции и у сайта разные источники.
Чтобы вызов функции выполнился успешно, функция должна поддерживать предварительный (preflight
Можно реализовать обработку preflight-запросов в функции Cloud Functions. Но существует простой способ решения этой проблемы — использовать для вызова функции API-шлюз с расширением спецификации [x-yc-apigateway-cors](*api_gw_cors).
Пример спецификации API-шлюза с расширением x-yc-apigateway-cors.
openapi: "3.0.0"
info:
version: 1.0.0
title: Mailer API
servers:
- url: https://d5dglu90r7y0********.wm******.apigw.yandexcloud.net
paths:
/register:
x-yc-apigateway-cors:
origin:
- https://my.example.com
methods:
- POST
post:
x-yc-apigateway-integration:
type: cloud_functions
function_id: d4edj6bo1uy0********
service_account_id: ajekjkm28y0********
API-шлюз, созданный по спецификации из примера, позволяет вызывать функцию Cloud Functions d4edj6bo1uy0******** по адресу https://d5dglu90r7y0********.wm******.apigw.yandexcloud.net/register со страниц сайта, размещенных на домене https://my.example.com.
Примечание
Поскольку функция d4edj6bo1uy0******** не является публичной, для ее вызова используется [сервисный аккаунт](*service_account), которому назначена [роль](*functions_invoker) functions.functionInvoker.
Схема работы решения для статического сайта с динамическими элементами:
Подробнее о том, как создать функцию Cloud Functions, читайте в разделах Создать функцию и Создать версию функции.
Подробнее о том, как создать API-шлюз, читайте в разделе Создание API-шлюза.
Сервис Yandex Cloud CDN можно использовать как глобальный балансировщик нагрузки для реализации отказоустойчивых сценариев. Так, с помощью групп источников можно организовать распределение запросов между несколькими источниками, размещенными у разных провайдеров, или настроить резервный источник на случай выхода из строя основного источника.
Подробнее о том, как работать с группами источников, читайте в разделе Группы источников.
Бакет Yandex Object Storage без публичного доступа с Yandex API Gateway и раздачей контента через Yandex Cloud CDN
Для реализации некоторых сценариев необходимо ограничить доступ к бакету или к части бакета. Например, для сайтов, которые должны содержать как публичный раздел, доступный любому посетителю, так и приватный, доступный только авторизованным пользователям.
Одним из способов реализовать такой сценарий является использование сервиса API Gateway и его расширений.
Схема работы решения:
Необходимые ресурсы
Чтобы разместить статический сайт в этом варианте решения, потребуются:
- бакет Object Storage с отключенным режимом
Хостинг; - API-шлюз API Gateway;
- CDN-ресурс Cloud CDN;
- доменное имя и SSL-сертификат, выпущенный для этого доменного имени;
- настроенная публичная зона DNS для домена и ресурсная запись, связывающая служебный домен API-шлюза и доменное имя.
В этом варианте решения не нужно присваивать бакету имя, соответствующее имени домена. Конечные пользователи будут обращаться не напрямую к бакету, а к API-шлюзу, с которым будет связано доменное имя.
Подробнее о том, как создать API-шлюз, читайте в разделе Создание API-шлюза.
Преимущества и недостатки этого варианта решения
|
Преимущества |
Недостатки |
|
|
Этот вариант размещения статического сайта не подходит для организации приватного корпоративного портала с доступом через VPN или Yandex Cloud Interconnect, так как API-шлюз всегда имеет публичный IP-адрес и для него отсутствуют встроенные средства ограничения доступа по IP-адресам.
Примечание
Ограничить доступ к API Gateway можно, только подключив профиль безопасности Yandex Smart Web Security и настроив ограничения доступа с помощью базовых правил. Для реализации сценария приватного корпоративного портала лучше подходит вариант размещения Бакет Yandex Object Storage без публичного доступа с Yandex Application Load Balancer.
Нюансы при реализации решения
Так как для бакета с выключенным публичным доступом нельзя включить режим Хостинг, настройте перенаправление запросов. В том числе обязательно настройте обработку запросов к корневой странице / так, чтобы в ответ на такой запрос пользователю возвращалось содержимое главной страницы сайта (чаще всего это файл index.html). Кроме того, настройте страницу с сообщением об ошибке, которая будет возвращаться вместе с ответом, содержащим код 4xx.
Пример конфигурации API-шлюза API Gateway.
openapi: "3.0.0"
info:
version: 1.0.0
title: Mailer API
servers:
- url: https://d5dglu90r7y0********.wm******.apigw.yandexcloud.net
- url: https://my.example.com
paths:
/:
get:
summary: Serve root page
parameters:
- name: file
in: path
required: true
schema:
type: string
x-yc-apigateway-integration:
type: object_storage
bucket: mysecretbucket0x7adfbu
object: index.html
error_object:
object: 404.html
statusCode: 404
service_account_id: ajebg5lgngy0********
/{file+}:
get:
summary: Serve static site content
parameters:
- name: file
in: path
required: true
schema:
type: string
x-yc-apigateway-integration:
type: object_storage
bucket: mysecretbucket0x7adfbu
object: '{file}'
error_object:
object: 404.html
statusCode: 404
service_account_id: ajebg5lgngy0********
Сервисному аккаунту с идентификатором ajebg5lgngy0******** должна быть выдана роль, разрешающая чтение из бакета mysecretbucket0x7adfbu.
Подробнее о том, как изменить настройки API-шлюза, читайте в разделе Изменить API-шлюз.
Решение проблем
Производительность API-шлюза позволяет обрабатывать значительное, но не бесконечное количество запросов в секунду. После достижения порога шлюз начнет возвращать ошибку 429 Too Many Requests.
Чтобы этого избежать, а также чтобы повысить доступность сайта под нагрузкой и снизить расходы, настройте CDN-ресурс, позволяющий кешировать запросы к сайту.
Совет
Дополнительно повысить производительность решения за счет использования еще одного кеширующего слоя позволит экранирование источников CDN-ресурса.
Подробнее о том, как создать CDN-ресурс, читайте в разделе Создание ресурса.
Задачей статических сайтов зачастую является привлечение пользователей с тем, чтобы они совершали на этих сайтах определенные целевые действия — переход по ссылке или заполнение регистрационной формы.
Нагрузка на обработчик данных регистрационных форм обычно носит неравномерный характер и может варьироваться от периодов длительного простоя до необходимости обрабатывать сотни запросов в секунду. В таких обстоятельствах удобным инструментом обработки запросов являются [функции](*function) Yandex Cloud Functions.
[Вызов](*function_call) функции осуществляется по специальному URL функции https://functions.yandexcloud.net/<идентификатор_функции>. При этом попытка прямого вызова функции со страницы сайта в браузере завершится ошибкой: браузер заблокирует запрос, поскольку у URL функции и у сайта разные источники.
Чтобы вызов функции выполнился успешно, функция должна поддерживать предварительный (preflight
Можно реализовать обработку preflight-запросов в функции Cloud Functions. Но существует простой способ решения этой проблемы — использовать для вызова функции API-шлюз с расширением спецификации [x-yc-apigateway-cors](*api_gw_cors).
Пример спецификации API-шлюза с расширением x-yc-apigateway-cors.
openapi: "3.0.0"
info:
version: 1.0.0
title: Mailer API
servers:
- url: https://d5dglu90r7y0********.wm******.apigw.yandexcloud.net
paths:
/register:
x-yc-apigateway-cors:
origin:
- https://my.example.com
methods:
- POST
post:
x-yc-apigateway-integration:
type: cloud_functions
function_id: d4edj6bo1uy0********
service_account_id: ajekjkm28y0********
API-шлюз, созданный по спецификации из примера, позволяет вызывать функцию Cloud Functions d4edj6bo1uy0******** по адресу https://d5dglu90r7y0********.wm******.apigw.yandexcloud.net/register со страниц сайта, размещенных на домене https://my.example.com.
Примечание
Поскольку функция d4edj6bo1uy0******** не является публичной, для ее вызова используется [сервисный аккаунт](*service_account), которому назначена [роль](*functions_invoker) functions.functionInvoker.
Схема работы решения с вызовом функции через API-шлюз:
Подробнее о том, как создать функцию Cloud Functions, читайте в разделах Создать функцию и Создать версию функции.
Бакет Yandex Object Storage без публичного доступа с Yandex Application Load Balancer
Чтобы создать статический сайт на основе бакета Object Storage без публичного доступа, вы можете использовать балансировщик нагрузки уровня приложений (L7-балансировщик).
L7-балансировщики при повышении нагрузки автоматически масштабируются, создавая новые ресурсные единицы, что позволяет им обеспечить существенно большую производительность, чем у API-шлюзов API Gateway.
Необходимые ресурсы
Чтобы разместить статический сайт в этом варианте решения, потребуются:
- бакет Object Storage с отключенным режимом
Хостинг; - L7-балансировщик нагрузки Application Load Balancer;
- доменное имя и SSL-сертификат, выпущенный для этого доменного имени;
- настроенная публичная зона DNS для домена и ресурсная запись, связывающая IP-адрес обработчика L7-балансировщика и доменное имя.
В этом варианте решения не нужно присваивать бакету имя, соответствующее имени домена. Конечные пользователи будут обращаться не напрямую к бакету, а к API-шлюзу, с которым будет связано доменное имя.
Подробнее о том, как создать L7-балансировщик нагрузки, читайте в разделе Создать L7-балансировщик.
Преимущества и недостатки этого варианта решения
|
Преимущества |
Недостатки |
|
|
Нюансы при реализации решения
L7-балансировщик Application Load Balancer обладает рядом особенностей, которые следует учитывать при реализации сценария:
-
При использовании балансировщика тарифицируются ресурсные единицы. При увеличении нагрузки на сайт количество ресурсных единиц может увеличиваться в соответствии с правилами масштабирования, что ведет к увеличению расходов.
Совет
Чтобы сократить издержки, при размещении публичного сайта подключите CDN-ресурс, позволяющий кешировать запросы к сайту. Дополнительно повысить производительность решения за счет использования еще одного кеширующего слоя позволит экранирование источников CDN-ресурса.
Для внутреннего балансировщика использовать кеширование Yandex Cloud CDN нельзя.
Подробнее о том, как создать CDN-ресурс, читайте в разделе Создание ресурса.
-
Так как для бакета с выключенным публичным доступом или с доступом через сервисное подключение нельзя включить режим Хостинг, на стороне балансировщика настройте обработку запросов к корневой странице
/так, чтобы в ответ на такой запрос пользователю возвращалось содержимое главной страницы сайта (чаще всего это файлindex.html).Подробнее о том, как настроить обработку запросов в балансировщике, читайте в разделе Изменить параметры HTTP-роутера.
-
L7-балансировщик не создает дополнительных (служебных) доменов.
Решение проблем
Ограничить доступ к данным бакета с использованием L7-балансировщика можно, заменив заголовок Referer на секретное слово и настроив для бакета политику доступа, которая разрешает доступ к контенту только при наличии у входящих запросов этого секретного слова в этом заголовке. Разрешить доступ к бакету только для ресурсных единиц Application Load Balancer нельзя, так как Application Load Balancer взаимодействует с бакетом через внутреннюю сервисную сеть.
Еще один способ ограничить доступ к данным бакета — использовать бакеты с доступом через сервисное подключение. Сервисные подключения позволяют создавать бакеты, доступные только по внутренним IP-адресам Yandex Virtual Private Cloud и недоступные через интернет. Этот способ подходит в случаях, когда к безопасности хранения данных предъявляются повышенные требования.
Подробнее о том, как настроить политику доступа для бакета, читайте в разделе Управление политикой доступа (bucket policy).
Задачей статических сайтов зачастую является привлечение пользователей с тем, чтобы они совершали на этих сайтах определенные целевые действия — переход по ссылке или заполнение регистрационной формы.
Нагрузка на обработчик данных регистрационных форм обычно носит неравномерный характер и может варьироваться от периодов длительного простоя до необходимости обрабатывать сотни запросов в секунду. В таких обстоятельствах удобным инструментом обработки запросов являются [функции](*function) Yandex Cloud Functions.
Вызов функции осуществляется по специальному URL функции https://functions.yandexcloud.net/<идентификатор_функции>. При этом попытка прямого вызова функции со страницы сайта в браузере завершится ошибкой: браузер заблокирует запрос, поскольку у URL функции и у сайта разные источники.
Чтобы вызов функции выполнился успешно, функция должна поддерживать предварительный (preflight
Реализовать обработку preflight-запросов можно в функции Cloud Functions.
Подробнее о том, как создать функцию Cloud Functions, читайте в разделах Создать функцию и Создать версию функции.