Обратный прокси-сервер в Azure Service Fabric
Обратный прокси-сервер, встроенный в Azure Service Fabric, помогает микрослужбам, работающим в кластере Service Fabric, обнаруживать другие службы с конечными точками HTTP и взаимодействовать с этими службами.
Модель взаимодействия с микрослужбами
Микрослужбы в Service Fabric выполняются на подмножестве узлов в кластере и по различным причинам могут перемещаться между ними. Поэтому конечные точки для микрослужб могут динамически изменяться. Чтобы обнаружить другие службы в кластере и взаимодействовать с ними, микрослужбам требуется выполнить следующие действия:
- Разрешение расположения службы через службу именования.
- Подключение к службе.
- Заключение описанных выше шагов в цикл, который реализует разрешение службы и политики повтора при сбое подключения.
Дополнительные сведения см. в разделе Подключение к службам в Service Fabric и взаимодействие с ними.
Обмен данными с использованием обратного прокси-сервера
Обратный прокси-сервер является службой, которая работает на каждом узле и обрабатывает разрешение конечных точек, автоматический повтор операций и другие сбои подключения от имени служб клиента. Обратный прокси-сервер можно настроить для применения различных политик при обработке запросов от служб клиента. Пи использовании обратного прокси-сервера служба клиента может использовать любые клиентские библиотеки связи HTTP и не требует специального разрешения и логики повтора в службе.
Обратный прокси-сервер предоставляет службам клиента одну или несколько конечных точек на локальном узле для отправки запросов к другим службам.
Примечание.
Поддерживаемые платформы
Обратный прокси-сервер в Service Fabric в настоящее время поддерживает следующие платформы:
- Кластер Windows: Windows 8 и более поздней версии или Windows Server 2012 и более поздней версии;
- Кластер Linux: сейчас обратный прокси-сервер для кластеров Linux недоступен.
Обращение к микрослужбам извне кластера
По умолчанию микрослужбы для внешнего взаимодействия используют модель участия: к любой службе нельзя получить доступ напрямую из внешних клиентов. Azure Load Balancer — это граница сети между микрослужбами и внешними клиентами, которая выполняет преобразование сетевых адресов и пересылает внешние запросы к внутренним конечным точкам "IP-адрес:порт". Чтобы внешние клиенты могли напрямую обращаться к конечной точке, нужно сначала настроить подсистему балансировки нагрузки для пересылки трафика каждого порта, используемого службой в кластере. Однако большинство микрослужб, особенно микрослужбы с отслеживанием состояния, не выполняются на всех узлах кластера. Микрослужбы могут перемещаться между узлами при отработке отказа. В таких случаях подсистема балансировки нагрузки не может эффективно определить расположение целевого узла реплик, к которым следует пересылать трафик.
Обращение к микрослужбам через обратный прокси-сервер извне кластера
Вместо того, чтобы настраивать порт отдельной службы в подсистеме балансировки нагрузки, в ней можно настроить порт обратного прокси-сервера. Такая конфигурация позволит клиентам, расположенным за пределами кластера, обращаться к службам внутри него через обратный прокси-сервер без дополнительных настроек.
Предупреждение
Настройка порта обратного прокси-сервера в подсистеме балансировки нагрузки обеспечит адресацию извне кластера всех микрослужб в этом кластере, которые предоставляют конечную точку HTTP. Это означает, пользователь-злоумышленник может обнаружить внутренние микрослужбы. Это представляет серьезную уязвимость, например:
- Пользователь-злоумышленник может многократно выполнять атаку типа "отказ в обслуживании", вызывая внутреннюю службу, у которой нет достаточно защищенного направления атак.
- Пользователь-злоумышленник может доставлять неправильно сформированные пакеты во внутреннюю службу, вызывая непредвиденное поведение.
- Внутренняя служба может возвращать персональные или конфиденциальные сведения, не предназначенные для предоставления службам вне кластера, в результате чего пользователь-злоумышленник может завладеть подобной информацией.
Вам следует тщательно изучить и устранить потенциальные угрозы безопасности для кластера и выполняющихся в нем приложений, прежде чем делать порт обратного прокси-сервера общедоступным.
Формат универсального кода ресурса (URI) для адресации служб через обратный прокси-сервер
Обратный прокси-сервер использует определенный формат универсального кода ресурса (URI), чтобы определять, в какую секцию службы следует перенаправить входящий запрос.
http(s)://<Cluster FQDN | internal IP>:Port/<ServiceInstanceName>/<Suffix path>?PartitionKey=<key>&PartitionKind=<partitionkind>&ListenerName=<listenerName>&TargetReplicaSelector=<targetReplicaSelector>&Timeout=<timeout_in_seconds>
http(s). Обратный прокси-сервер можно настроить для приема трафика HTTP или HTTPS. После настройки обратного прокси-сервера для прослушивания по протоколу HTTPS ознакомьтесь со сведениями о переадресации HTTPS в статье Подключение к безопасной службе с помощью обратного прокси-сервера.
Cluster FQDN | internal IP. Для внешних клиентов обратный прокси-сервер можно настроить таким образом, чтобы он был доступен через домен кластера (например, mycluster.eastus.cloudapp.azure.com). По умолчанию обратный прокси-сервер выполняется на каждом узле. Для внутреннего трафика он может быть доступен на узле localhost или по IP-адресу любого внутреннего узла (например, 10.0.0.1).
Port. Порт, например 19081, указанный для обратного прокси-сервера.
ServiceInstanceName. Полное имя развернутого экземпляра службы, к которому вы пытаетесь получить доступ, без использования схемы fabric:/. Например, чтобы подключиться к службе fabric:/myapp/myservice/, используется имя myapp/myservice.
В имени экземпляра службы учитывается регистр. Использование символов разного регистра в имени экземпляра службы в URL-адресе приводит к сбою запросов с ошибкой "404 (не найдено)".
Suffix path. Фактический URL-адрес службы, к которой вы подключаетесь, например myapi/values/add/3.
PartitionKey. Для секционированной службы это вычисляемый ключ секции, к которой вы подключаетесь. Обратите внимание, что это не идентификатор GUID секции. Этот параметр не является обязательным для служб, использующих схему одноэлементного секционирования.
PartitionKind. Схема секционирования службы. Это может иметь значение "Int64Range" (Диапазон Int64) или "Named" (Именованная). Этот параметр не является обязательным для служб, использующих схему одноэлементного секционирования.
ListenerName. Конечные точки, представляемые службой, имеют следующий вид: {"Endpoints":{"Listener1":"Endpoint1","Listener2":"Endpoint2" ...}} Если служба представляет несколько конечных точек, то данный параметр определяет, к которой из них следует перенаправить клиентский запрос. При наличии только одного прослушивателя потребность в данном параметре отсутствует.
TargetReplicaSelector. Данный параметр определяет, каким образом должна быть выбрана целевая реплика или экземпляр.
- Если целевая служба является службой с отслеживанием состояния, то параметр TargetReplicaSelector может иметь значение PrimaryReplica, RandomSecondaryReplica или RandomReplica. Если этот параметр не указан, по умолчанию используется значение PrimaryReplica.
- Если целевая служба является службой без отслеживания состояния, обратный прокси-сервер выбирает случайный экземпляр раздела службы, к которому направляется запрос.
Timeout. Время ожидания для HTTP-запроса к службе, созданного обратным прокси-сервером от имени клиентского запроса. Значение по умолчанию — 120 секунд. Этот параметр является необязательным.
Пример использования
Для примера рассмотрим службу fabric:/MyApp/MyService, которая открывает прослушиватель HTTP по приведенному ниже URL-адресу.
http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/
Ниже приведены ресурсы для службы.
/index.html
/api/users/<userId>
Если служба использует схему одноэлементного секционирования, то параметры строки запроса PartitionKey и PartitionKind можно не указывать и к службе можно обратиться через шлюз следующим образом.
- Извне:
http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService
- Изнутри:
http://localhost:19081/MyApp/MyService
.
Если служба использует схему секционирования Uniform Int64, для обращения к секции службы необходимо использовать параметры строки запроса PartitionKey и PartitionKind.
- Извне:
http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64Range
- Изнутри:
http://localhost:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64Range
.
Укажите путь к ресурсу после имени службы в URL-адресе, чтобы обратиться к предоставленным службой ресурсам.
- Извне:
http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService/index.html?PartitionKey=3&PartitionKind=Int64Range
- Изнутри:
http://localhost:19081/MyApp/MyService/api/users/6?PartitionKey=3&PartitionKind=Int64Range
.
Затем шлюз перешлет эти запросы по URL-адресу службы.
http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/index.html
http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/api/users/6
Специальные действия для служб с общим доступом к портам
Обратный прокси-сервер Service Fabric пытается повторно разрешить адрес службы и повторить запрос, если служба недоступна. Как правило, недоступность службы означает, что экземпляр или реплика службы была перемещена на другой узел в ходе обычного жизненного цикла. В этом случае обратный прокси-сервер может получить ошибку сетевого подключения, указывающую, что конечная точка больше не открыта по первоначально разрешенному адресу.
Тем не менее реплики или экземпляры службы могут совместно использовать хост-процесс и даже порт при размещении на веб-сервере на основе http.sys, включая:
В этом случае вполне вероятно, что веб-сервер доступен в хост-процессе и отвечает на запросы, но разрешенный экземпляр или реплика службы больше не доступна на узле. В этом случае шлюз получит от веб-сервера ответ "HTTP 404". Таким образом, ответ "HTTP 404" может иметь два различных значения:
- Случай № 1. Адрес службы указан правильно, но запрошенный пользователем ресурс не существует.
- Случай № 2. Адрес службы указан неправильно, а запрошенный пользователем ресурс может существовать на другом узле.
В первом случае это обычная ошибка "HTTP 404", которая считается ошибкой пользователя. Однако во втором случае пользователь запросил ресурс, который существует. Обратному прокси-серверу не удалось найти его, так как была перемещена сама служба. Обратному прокси-серверу необходимо еще раз разрешить адрес и повторить запрос.
Таким образом, обратному прокси-серверу необходим способ, позволяющий различать эти два случая. Для этого требуется указание от сервера.
По умолчанию обратный прокси-сервер предполагает, что произошел второй случай, и пытается повторить разрешение адреса службы и отправку запроса.
Чтобы указать обратному прокси-серверу, что это первый случай, служба должна вернуть следующий заголовок ответа HTTP:
X-ServiceFabric : ResourceNotFound
Этот заголовок ответа HTTP указывает обычную ситуацию возникновения ошибки "HTTP 404", в которой запрошенный ресурс не существует, и обратный прокси-сервер не будет пытаться повторно разрешить адрес службы.
Специальные действия для служб, запущенных в контейнерах
Чтобы создать URL-адрес обратного прокси-сервера для запущенных в контейнерах служб, можно использовать переменную среды Fabric_NodeIPOrFQDN
, как в следующем коде:
var fqdn = Environment.GetEnvironmentVariable("Fabric_NodeIPOrFQDN");
var serviceUrl = $"http://{fqdn}:19081/DockerSFApp/UserApiContainer";
По умолчанию переменная Fabric_NodeIPOrFQDN
для локального кластера имеет значение localhost. Запустите локальный кластер, указав параметр -UseMachineName
, чтобы гарантировать, что контейнеры имеют доступ к обратному прокси-серверу, работающему на узле. Дополнительные сведения см. в разделе Настройка среды разработчика для отладки контейнеров.
Службам Service Fabric, выполняющимся в контейнерах Docker Compose, требуется особая конфигурация http: или https: в разделе Ports файла docker-compose.yml. Дополнительные сведения см. в разделе Поддержка развертывания Docker Compose в Azure Service Fabric (предварительная версия).
Следующие шаги
- Установка и настройка обратного прокси-сервера в кластере
- Подключение к защищенной службе с помощью обратного прокси-сервера
- Диагностика событий обратного прокси-сервера
- Пример обмена данными по протоколу HTTP между службами представлен в примере проекта на сайте GitHub.
- Удаленное взаимодействие службы с Reliable Services
- Начало работы со службами веб-API Microsoft Azure Service Fabric с саморазмещением OWIN
- Коммуникационный стек WCF для надежных служб