Поделиться через


Обратный прокси-сервер в Azure Service Fabric

Обратный прокси-сервер, встроенный в Azure Service Fabric, помогает микрослужбам, работающим в кластере Service Fabric, обнаруживать другие службы с конечными точками HTTP и взаимодействовать с этими службами.

Модель взаимодействия с микрослужбами

Микрослужбы в Service Fabric выполняются на подмножестве узлов в кластере и по различным причинам могут перемещаться между ними. Поэтому конечные точки для микрослужб могут динамически изменяться. Чтобы обнаружить другие службы в кластере и взаимодействовать с ними, микрослужбам требуется выполнить следующие действия:

  1. Разрешение расположения службы через службу именования.
  2. Подключение к службе.
  3. Заключение описанных выше шагов в цикл, который реализует разрешение службы и политики повтора при сбое подключения.

Дополнительные сведения см. в разделе Подключение к службам в 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 (предварительная версия).

Следующие шаги