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


Служба DNS в Azure Service Fabric

Служба DNS — это необязательная системная служба, которую можно включить в кластере для обнаружения других служб с помощью протокола DNS.

Многие службы, особенно контейнерные службы, могут обращаться через существующий URL-адрес. Возможность разрешать эти службы с помощью стандартного протокола DNS, а не протокола службы именования Service Fabric, желательно. Служба DNS позволяет сопоставлять DNS-имена с именем службы и, таким образом, определять IP-адреса конечных точек. Такая функциональность обеспечивает переносимость контейнерных служб на разных платформах и упрощает сценарии "лифт и смена", позволяя использовать существующие URL-адреса службы, а не переписать код для использования службы именования.

Служба DNS сопоставляет DNS-имена с именами служб, которые, в свою очередь, разрешаются службой именования для возврата конечной точки службы. DNS-имя службы предоставляется во время создания. На следующей схеме показано, как служба DNS работает для бесстатусных служб. Для краткости схемы отображают только одну конечную точку для служб, хотя каждая служба может иметь несколько конечных точек.

Схема, показывающая, как DNS-имена сопоставляются с именами служб DNS для служб без отслеживания состояния.

Начиная с версии 6.3 Service Fabric, протокол DNS Service Fabric был расширен, чтобы включить схему адресации секционированных stateful служб. Эти расширения позволяют разрешать определенные IP-адреса разделов с помощью сочетания DNS-имени службы с отслеживаемым состоянием и имени раздела. Поддерживаются все три схемы секционирования:

  • Именованное секционирование
  • Диапазонное секционирование
  • Одноэлементное секционирование

На следующей схеме показано, как служба DNS работает для разделённых сервисов с отслеживанием состояния.

Схема, показывающая, как DNS-имена сопоставляются с именами служб с помощью службы DNS для секционированных служб с сохранением состояния.

Дополнительные сведения о секционированных запросах см. в разделе ниже.

Поддержка ОС

Служба DNS поддерживается как в кластерах Windows, так и в Linux, хотя поддержка Linux в настоящее время ограничена контейнерными службами и не может быть включена через портал Azure. Однако Windows поддерживает все типы служб и модели развертывания.

Включение службы DNS

Замечание

Включение службы DNS переопределит некоторые параметры DNS на узлах. Если у вас возникли проблемы с подключением к Интернету, проверьте параметры DNS.

Новые кластеры

Кластеры с помощью шаблонов ARM

Чтобы развернуть новый кластер с помощью шаблонов ARM, можно использовать примеры шаблонов или написать собственные. Если это еще не сделано, служба DNS может быть включена в шаблонах с помощью минимальных поддерживаемых версий API и путем добавления соответствующих параметров. Подробные сведения о том, как это сделать, можно увидеть ниже в пунктах 1 и 2 нумерованного списка.

Кластеры с помощью портала Azure

Если вы создаете стандартный кластер на портале, служба DNS включена по умолчанию в параметре "Включить службу DNS " в разделе "Добавление компонентов ".

Снимок экрана: включение службы DNS для стандартного кластера на портале.

Если вы создаете управляемый кластер на портале, служба DNS включена по умолчанию в параметре службы DNS в разделе "Добавление компонентов ".

Снимок экрана: включение службы DNS для управляемого кластера с помощью портала.

Существующие кластеры

Если вы обновляете существующий управляемый кластер, чтобы включить службу DNS, вы можете сделать это на портале, перейдя на страницу служб надстройки на странице ресурсов кластера. В противном случае можно включить службу DNS с помощью альтернативных методов, на которые ссылается следующая ссылка:

  • Используйте шаблон ARM, который использовался для развертывания кластера, если применимо.
  • Перейдите к кластеру в обозревателе ресурсов Azure и обновите ресурс кластера, как показано ниже (на шаге 2 и далее).
  • Перейдите к кластеру на портале и нажмите кнопку "Экспорт шаблона". Дополнительные сведения см. в статье "Экспорт шаблона из группы ресурсов".

После создания шаблона можно включить службу DNS с помощью следующих действий:

  1. Для стандартных кластеров убедитесь, что для ресурса Microsoft.ServiceFabric/clusters установлена версия apiVersion2017-07-01-preview или более поздняя, а если нет, обновите её, как показано в следующем примере:

    {
        "apiVersion": "2017-07-01-preview",
        "type": "Microsoft.ServiceFabric/clusters",
        "name": "[parameters('clusterName')]",
        "location": "[parameters('clusterLocation')]",
        ...
    }
    

    Для управляемых кластеров убедитесь, что ресурс Microsoft.ServiceFabric/managedClusters имеет значение apiVersion, установленное на 2020-01-01-preview или более позднюю версию, а если нет, обновите его, как показано в следующем примере:

    {
        "apiVersion": "2020-01-01-preview",
        "type": "Microsoft.ServiceFabric/managedClusters",
        "name": "[parameters('clusterName')]",
        "location": "[parameters('clusterLocation')]",
        ...
    }
    
  2. Теперь включите службу DNS одним из следующих способов:

    • Чтобы включить службу DNS с параметрами по умолчанию, добавьте ее addonFeatures в раздел внутри properties раздела, как показано в следующем примере:

      "properties": {
        ...
        "addonFeatures": [
          "DnsService"
          ],
        ...
      }
      
    • Чтобы включить службу с настройками, отличными от параметров по умолчанию, добавьте DnsService раздел в раздел fabricSettings внутри properties раздела. В данном случае вам не нужно добавлять службу DnsService в addonFeatures. Дополнительные сведения о свойствах, которые можно задать для службы DNS, см. в разделе параметров службы DNS.

      "properties": {
       ...
       "fabricSettings": [
         ...
         {
           "name": "DnsService",
           "parameters": [
             {
               "name": "IsEnabled",
               "value": "true"
             },
             {
               "name": "<key>",
               "value": "<value>"
             }
           ]
         },
         ...
       ]
      }
      
  3. После того как вы обновите шаблон кластера с вашими изменениями, примените их и завершите обновление. По завершении обновления служба системы DNS запускается в кластере. Имя службы — fabric:/System/DnsService, и вы можете найти его в разделе Системная служба в обозревателе Service Fabric.

Замечание

При обновлении DNS с отключенного на включенное инструмент Service Fabric Explorer может не отразить новое состояние. Чтобы устранить проблему, перезапустите узлы, изменив политику обновления в шаблоне.

Настройка DNS-имени для службы

Dns-имена для служб можно задать с помощью шаблонов ARM, служб по умолчанию в файле ApplicationManifest.xml или с помощью команд PowerShell.

Удалось разрешить DNS-имя вашей службы на всех узлах кластера, поэтому особенно важно обеспечить уникальность этого DNS-имени во всем кластере.

Настоятельно рекомендуется использовать схему именования <ServiceName>.<AppName>, например service1.application1. Если приложение развертывается с помощью Docker Compose, службы автоматически назначаются DNS-имена с помощью этой схемы именования.

Настройка DNS-имени с помощью шаблона ARM

Если вы используете шаблоны ARM для развертывания служб, вы можете добавить serviceDnsName свойство в соответствующий раздел и назначить ему значение. Ниже приведены примеры.

Стандартные кластеры

Для стандартных кластеров убедитесь, что apiVersion установлен на 2019-11-01-preview или более позднюю версию для ресурса Microsoft.ServiceFabric/clusters/applications/services, и если это не так, обновите его, как показано в следующем примере:

{
  "apiVersion": "2019-11-01-preview",
  "type": "Microsoft.ServiceFabric/clusters/applications/services",
  "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
  "location": "[variables('clusterLocation')]",
  "dependsOn": [
    "[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
  ],
  "properties": {
    "provisioningState": "Default",
    "serviceKind": "Stateless",
    "serviceTypeName": "[parameters('serviceTypeName')]",
    "instanceCount": "-1",
    "partitionDescription": {
      "partitionScheme": "Singleton"
    },
    "correlationScheme": [],
    "serviceLoadMetrics": [],
    "servicePlacementPolicies": [],
    "serviceDnsName": "[parameters('serviceDnsName')]"
  }
}

Управляемые кластеры

Для управляемых кластеров убедитесь, что для ресурса Microsoft.ServiceFabric/managedclusters/applications/services свойство apiVersion установлено на значение 2022-10-01-preview или более позднее, и, если нет, обновите его, как показано в следующем примере:

{
  "apiVersion": "2022-10-01-preview",
  "type": "Microsoft.ServiceFabric/managedclusters/applications/services",
  "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
  "location": "[variables('clusterLocation')]",
  "dependsOn": [
    "[concat('Microsoft.ServiceFabric/managedclusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
  ],
  "properties": {
    "serviceKind": "Stateless",
    "serviceTypeName": "[parameters('serviceTypeName')]",
    "instanceCount": "-1",
    "partitionDescription": {
      "partitionScheme": "Singleton"
    },
    "correlationScheme": [],
    "serviceLoadMetrics": [],
    "servicePlacementPolicies": [],
    "serviceDnsName": "[parameters('serviceDnsName')]"
  }
}

Задание DNS-имени для службы по умолчанию в ApplicationManifest.xml

Откройте проект в Visual Studio или избранном редакторе и откройте файл ApplicationManifest.xml. Перейдите в раздел служб по умолчанию и для каждой ServiceDnsName службы добавьте атрибут. В следующем примере показано, как задать DNS-имя службы для stateless1.application1

<Service Name="Stateless1" ServiceDnsName="stateless1.application1">
  <StatelessService ServiceTypeName="Stateless1Type" InstanceCount="[Stateless1_InstanceCount]">
    <SingletonPartition />
  </StatelessService>
</Service>

В следующем примере DNS имя для динамического сервиса задано stateful1.application1. Служба использует именованную схему секционирования. Обратите внимание, что имена разделов имеют нижний регистр. Это требование для разделов, предназначенных для запросов DNS; дополнительную информацию см. в статье "Выполнение DNS-запросов на разделе с отслеживанием состояния".

<Service Name="Stateful1" ServiceDnsName="stateful1.application1" />
  <StatefulService ServiceTypeName="Stateful1Type" TargetReplicaSetSize="2" MinReplicaSetSize="2">
    <NamedPartition>
      <Partition Name="partition1" />
      <Partition Name="partition2" />
    </NamedPartition>
  </StatefulService>
</Service>

Настройка DNS-имени для службы с помощью PowerShell

При создании службы можно задать DNS-имя, используя New-ServiceFabricService команду PowerShell. В следующем примере создается новая служба без состояния с DNS-именем stateless1.application1:

New-ServiceFabricService `
    -Stateless `
    -PartitionSchemeSingleton `
    -ApplicationName fabric:/application1 `
    -ServiceName fabric:/application1/stateless1 `
    -ServiceTypeName Stateless1Type `
    -InstanceCount 1 `
    -ServiceDnsName stateless1.application1

Вы также можете обновить существующую службу с помощью Update-ServiceFabricService команды PowerShell. В следующем примере обновляется существующая служба без отслеживания состояния, чтобы добавить DNS-имя stateless1.application1:

Update-ServiceFabricService `
    -Stateless `
    -ServiceName fabric:/application1/stateless1 `
    -ServiceDnsName stateless1.application1

Убедитесь, что DNS-имя задано в Service Fabric Explorer

После развертывания службы с DNS-именем Service Fabric Explorer отобразит DNS-имя службы, как показано на следующем рисунке:

Снимок экрана: DNS-имя в Service Fabric Explorer.

Замечание

Это представление может отличаться в зависимости от используемой версии Service Fabric Explorer, однако поле DNS-имени должно отображаться в какой-то форме на странице службы.

Выполнение DNS-запросов на раздел службы с отслеживанием состояния

Начиная с Service Fabric версии 6.3 служба DNS поддерживает запросы к секциям служб. Чтобы включить поддержку запросов секционированных служб, параметры службы DNS необходимо обновить, чтобы задать параметр EnablePartitionedQuerytrue.

Для секций, которые будут использоваться в DNS-запросах, применяются следующие ограничения именования:

  • Имена секций должны соответствовать DNS.
  • Имена разделов с несколькими метками, включая точку или '.', не следует использовать.
  • Названия разделов следует писать строчными.

DNS-запросы, предназначенные для секции, форматируются следующим образом:

    <First-Label-Of-Partitioned-Service-DNSName><PartitionPrefix><Target-Partition-Name><PartitionSuffix>.<Remaining-Partitioned-Service-DNSName>

Где:

  • First-Label-Of-Partitioned-Service-DNSName — это первая часть DNS-имени службы.
  • PartitionPrefix — это значение, которое можно задать в разделе DnsService манифеста кластера или с помощью шаблона ARM кластера. Значение по умолчанию — "-". Дополнительные сведения см. в разделе параметров службы DNS.
  • Целевой раздел — это имя раздела.
  • PartitionSuffix — это значение, которое можно задать в разделе DnsService манифеста кластера или с помощью шаблона ARM кластера. Значение по умолчанию — пустая строка. Дополнительные сведения см. в разделе параметров службы DNS.
  • Оставшаяся часть DNS-имени службы — это часть вашего DNS-имени службы.

В следующих примерах показаны запросы DNS для секционированных служб, работающих в кластере с параметрами по умолчанию для PartitionPrefix и PartitionSuffix:

  • Чтобы разрешить часть "0" службы с DNS-именем backendrangedschemesvc.application, использующим схему диапазонного секционирования, используйте backendrangedschemesvc--0.application.
  • Чтобы разрешить раздел "first" службы с DNS-именем backendnamedschemesvc.application, которая использует именованную схему разделения, используйте backendnamedschemesvc--first.application.

Служба DNS возвращает IP-адрес конечной точки, связанной с первичной репликой секции. Если секция не указана, служба DNS случайно выбирает секцию.

Использование DNS-имен в службах

При развертывании служб с DNS-именами можно найти IP-адрес предоставляемых конечных точек, ссылаясь на DNS-имя. Служба DNS работает для служб без отслеживания состояния, а в Service Fabric версии 6.3 и более поздних версиях также для служб с отслеживанием состояния. Для служб с отслеживанием состояния, работающих в версиях Service Fabric до 6.3, можно использовать встроенную службу обратного прокси-сервера для вызовов HTTP для вызова определенной секции службы.

Динамические порты не поддерживаются службой DNS. Для разрешения служб, использующих динамические порты, можно использовать обратную прокси-службу.

В следующем коде показано, как вызывать службу без отслеживания состояния через DNS. Это просто обычный HTTP-вызов, в котором вы предоставляете DNS-имя, порт и любой необязательный путь в рамках URL-адреса.

public class ValuesController : Controller
{
    // GET api
    [HttpGet]
    public async Task<string> Get()
    {
        string result = "";
        try
        {
            Uri uri = new Uri("http://stateless1.application1:8080/api/values");
            HttpClient client = new HttpClient();
            var response = await client.GetAsync(uri);
            result = await response.Content.ReadAsStringAsync();

        }
        catch (Exception e)
        {
            Console.Write(e.Message);
        }

        return result;
    }
}

В следующем коде показан вызов на конкретный раздел службы с сохранением состояния. В этом случае DNS-имя содержит имя секции (partition1). Вызов предполагает кластер с значениями по умолчанию для PartitionPrefix и PartitionSuffix.

public class ValuesController : Controller
{
    // GET api
    [HttpGet]
    public async Task<string> Get()
    {
        string result = "";
        try
        {
            Uri uri = new Uri("http://stateful1--partition1.application1:8080/api/values");
            HttpClient client = new HttpClient();
            var response = await client.GetAsync(uri);
            result = await response.Content.ReadAsStringAsync();

        }
        catch (Exception e)
        {
            Console.Write(e.Message);
        }

        return result;
    }
}

Рекурсивные запросы

Для DNS-имен, которые служба DNS не может разрешать самостоятельно (например, общедоступное DNS-имя), он перенаправит запрос на существующие рекурсивные DNS-серверы на узлах.

Схема, показывающая, как разрешаются запросы DNS для общедоступных имен.

До Service Fabric 9.0 эти серверы последовательно запрашиваются до получения ответа с фиксированным периодом ожидания в 5 секунд между ними. Если сервер не ответил в течение периода ожидания, следующий сервер (если он доступен) будет запрашиваться. В случае, если эти DNS-серверы столкнулись с любыми проблемами, завершение запросов DNS займет больше 5 секунд, что не идеально.

Начиная с Service Fabric 9.0 добавлена поддержка параллельных рекурсивных запросов. При параллельных запросах можно одновременно инициировать контакт со всеми рекурсивными DNS-серверами, и выигрывает тот, чей ответ поступает первым. Это приводит к более быстрым ответам в сценарии, который ранее упоминалось. Этот параметр по умолчанию не включен.

В Service Fabric 9.0 также представлены точные параметры для управления поведением рекурсивных запросов, включая периоды ожидания и попытки запроса. Эти параметры можно задать в параметрах службы DNS:

  • RecursiveQuerySerialMaxAttempts — количество последовательных запросов, которые будут предприняты в большинстве случаев. Если это число больше, чем число DNS-серверов для пересылки, запрос будет прекращен после того, как на каждый сервер был сделан один запрос.
  • RecursiveQuerySerialTimeout — значение времени ожидания в секундах для каждого предпринятого последовательного запроса.
  • RecursiveQueryParallelMaxAttempts: максимальное количество попыток выполнения параллельных запросов. Параллельные запросы выполняются после исчерпания максимальных попыток для серийных запросов.
  • RecursiveQueryParallelTimeout — значение времени ожидания в секундах для каждого предпринятого параллельного запроса.

Ограничения и известные проблемы

  • Динамические порты не поддерживаются службой DNS. Чтобы разрешить службы, предоставляемые в динамических портах, используйте обратную прокси-службу.
  • Поддержка Linux в настоящее время ограничена контейнерными службами. В настоящее время службы на основе процессов в Linux не могут использовать службу DNS.
  • Служба DNS для кластеров Linux не может быть включена на портале Azure.
  • Если DNS-имя изменено для службы, обновления имен могут не сразу отображаться в некоторых сценариях. Чтобы устранить проблему, экземпляры службы DNS следует перезапустить в кластере.

Дальнейшие шаги

Узнайте больше о коммуникации служб в кластере с взаимодействием с сервисами